[33-js-concepts] 18. Object.create and Object.assign

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 }
  • 매개변수 순서에 따라 오버라이딩 되는 것을 알 수 있습니다.

 

단점

  • 객체 속성을 병합만 하기 때문에 깊은 복사를 할 수 없다.
  • 깊은 복사를 하기 위해선 다른 대안을 생각해야 한다.

댓글(0)

Designed by JB FACTORY