Object.create의 배경
- 자바스크립트의 상속
- 자바스크립트만으로 웹페이지의 동작을 구현하기 시작하면서 객체지향의 개념이 집중되게 되었다.
- new를 이용한 상속 (prototype)
function Person() {
this.name = "anonymous";
this.job = "none";
this.sayHello = function () {
alert("Hello, my name is " + this.name);
};
}
function Unikys() {
this.name = "Unikys";
this.job = "Programmer";
}
Unikys.prototype = new Person();
var unikys = new Unikys();
unikys.sayHello(); // Hello, my name is Unikys
- prototype chain
- constructor가 있는 prototype을 다른 새로운 객체로 덮어씌우게 되면 원래 자기 자신의 constructor는 상실하게 되고, 수정한 객체 constructor로 바뀌게 된다.
Object.create
- 자바스크립트 개발자들은 내부에서 이렇게 constructor가 망가지는 것을 원하지 않았기 때문에 고안한 것이 Object.create 함수이다.
-
new를 사용한 객체의 생성이 '자바스크립트스럽지 않다'라는 의견과 new라는 키워드의 사용을 자제하고 싶어하는 사람들이 별도로 객체를 생성하는 함수를 제안하게 되고 ECMA5 표준규격에 추가
Object.create = function (obj) {
function F() {}
F.prototype = obj;
return new F();
}
- Douglas Crockford란 사람이 이 Object.create 형태를 처음으로 주장했다.
- Object.create는 이 형태로 돌아가고 있다고 볼 수 있다.
- 특이점은 parameter로 들어오는 obj는 상속할 객체가 아닌, prototype으로 설정할 객체라는 점이다.
상속방법
function Person(name) {
this.name = name; };Person.prototype = { yell: function () { alert("My name is " + this.name); } }; var unikys = Object.create(Person.prototype); // person 상속unikys.name = "Unikys"; unikys.yell();
-
Person을 직접 넘겨주지 않고, prototype을 넘겨주는 것은 위의 특징과 같이 F 함수의 prototype으로 설정하고 있는것
-
생성자가 호출 되지 않았고 오로지 prototype만을 넘겨줬다.
-
Object.create는 선택적으로 2번째 인자를 받음으로써 생성하는 객체를 초기화 시킬수있다.
-
객체를 초기화시 Object.defineProperties() 를 통해 객체의 속성이 정의 된다.
writable, enumerable, configurable 속성은 false
생성자 호출
var unikys = Object.create(Person.prototype);
Person.call(unikys, "Unikys");
unikys.yell(); // "My name is Unikys"
-
Object.create를 사용하게 되면 new와는 비슷하지만 생성자 호출을 직접해야한다.
new 와 Object.create의 결합
Unikys.prototype = Object.create(Person.prototype); //prototype 상속
Unikys.prototype.constructor = Unikys; // 깨진 constructor 링크를 제대로 수정
var unikys = new Unikys();
-
Object.create를 사용할때 new를 이용하여 객체를 생성하는 방법에 이미 익숙해져있다면 다소 귀찮을 것이다.
-
prototype으로 설정하는 객체를 Object.create로 설정하면서 constructor를 다시 설정해주면 된다.
-
이 방법은 기존에 자바스크립트가 그대로 안고 가고 있었던 문제들을 해결하는 방법이기도 하다.
Create.object 언제 사용??
-
new가 object.create()를 100% 호환하고 있으므로, 굳이 생소한 Object.create를 쓰진 않을 것 같다.
-
2013년 기준 수행 명령 횟수 성능비교 (ECMA2015)
-
성능도 포함하여 비교하자면 많이 쓰이진 않을 것 같다.
Object.assign
Object.assign(target, ...sources)
- 첫번째 인자가 target이고, 그 뒤의 인자들이 소스 객체들입니다.
- target을 대상으로 sources들이 병합됩니다.
- return값으로 병합된 target 객체를 반환합니다.
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 }; const returnedTarget = Object.assign(target, source);
console.log(target); // Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget); // Object { a: 1, b: 4, c: 5 }
중복된 속성들을 병합할 때
var o1 = { a: 1, b: 1, c: 1 }; var o2 = { b: 2, c: 2 }; var o3 = { c: 3 }; var obj = Object.assign({}, o1, o2, o3); console.log(obj); // { a: 1, b: 2, c: 3 }
- 매개변수 순서에 따라 오버라이딩 되는 것을 알 수 있습니다.
단점
- 객체 속성을 병합만 하기 때문에 깊은 복사를 할 수 없다.
- 깊은 복사를 하기 위해선 다른 대안을 생각해야 한다.