JavaScript/JavaScript 문법

[JavaScript]Object.assign() 함수와 Object.create()의 차이점

DevStory 2021. 11. 16.

이번 포스팅에서는 Object.assign() 함수와 Object.create() 함수의 차이점을 소개합니다.

 


Object.assign() 함수

Object.assign() 함수는 열거 가능한 속성(enumerable properties)을 복사하여 새로운 객체를 반환합니다.

 

위에서 언급한 열거 가능한 속성은 for...in 루프 또는 Object.keys() 함수를 사용하여 접근할 수 있는 속성을 의미합니다.

 

다음 코드는 for...in 루프를 사용하여 student의 모든 속성을 접근하는 예제입니다.

const student = {
    code: 1000,
    name: 'Kang',
    age: 29
};

for (const key in student) {
    console.log(key)
};

실행 결과

다음 코드는 student 객체의 age 속성을 비열거형으로 설정 후 for...in 루프를 사용하여 student의 속성을 접근합니다.

const student = {
    code: 1000,
    name: 'Kang',
    age: 29
};

// student의 age속성을 비열거형으로 설정
Object.defineProperty(student, 'age', {
    enumerable: false
});

for (const key in student) {
    console.log(key)
};

실행 결과

student의 age속성이 비열거형으로 변경되었으므로 for...in 루프로 접근이 불가능합니다.

 

이제 Object.assign() 함수 사용 방법을 알아보겠습니다.

 

Object.assign() 함수의 구문은 다음과 같습니다.

Object.assign(target, ...sources)

첫 번째 인수인 target은 복사된 속성이 반영되는 객체입니다.

 

두 번째 인수인 sources는 첫 번째 인수인 target에 반영하고자 하는 속성들을 가지는 객체들입니다.

 

반환 값은 sources의 속성들이 target에 반영된 객체입니다.

 

다음은 Object.assign() 함수에서 빈 객체를 첫 번째 매개 변수로 하고 source을 두 번째 매개변수로 설정하여 source의 속성이 반영된 새로운 객체를 생성하는 예제입니다.

const source = {
  prop1: true,
  prop2: 'false'
};

const returnedTarget = Object.assign({}, source); 
// {prop1: true, prop2: "false"}

 

다음은 Object.assign() 함수에서 첫 번째 매개변수가 빈 객체가 아닌 경우입니다.

const target = {
  prop3: 'Hi'
}

const source = {
  prop1: true,
  prop2: 'false'
};

const returnedTarget = Object.assign(target, source); 

console.log('target Object');
console.log(target);
// {prop1: true, prop2: "false", prop3: "Hi"}

console.log('returnedTarget');
console.log(returnedTarget);
// {prop1: true, prop2: "false", prop3: "Hi"}

실행 결과

source의 속성이 target에 반영되었으며, Object.assign() 함수가 반환하는 값은 첫 번째 매개변수와 동일합니다.

 

즉, Object.assign() 함수의 매개변수가 빈 객체( { } )가 아닌 경우 반환 값은 첫 번째 매개변수와 동일합니다.

 

다음과 soucres가 여러개인 경우입니다.

const target = {
  prop3: 'Hi'
}

const source1 = {
  prop1: true,
  prop2: 'false'
};

const source2 = {
  prop4: true,
  prop5: 'false'
};

const returnedTarget = Object.assign(target, source1, source2); 
// {prop1: true, prop2: "false", prop3: "Hi", prop4: true, prop5: "false"}

source1의 속성과 source2의 속성이 target에 반영됩니다.

 

다음은 target과 source가 동일한 속성을 가지는 경우입니다.

const target = {
  prop1: 'Hi'
}

const source = {
  prop1: true,
  prop2: 'false'
};

const returnedTarget = Object.assign(target, source); 

console.log('target Object');
console.log(target);
// {prop1: true, prop2: "false"}

console.log('returnedTarget');
console.log(returnedTarget);
// {prop1: true, prop2: "false"}

실행 결과

target과 source가 동일한 속성을 갖는 source 객체의 속성 값으로 덮어씁니다.


Object.create() 함수

Object.create() 함수는 기존 객체를 프로토타입으로 새로운 객체를 반환합니다.

 

다음 코드는 source 객체가 반환된 객체의 프로토타입으로 생성됩니다.

const source = {
  prop1: true,
  prop2: 'false'
};

const returnedTarget = Object.create(source); 

console.log('source');
console.log(source);

console.log('returnedTarget');
console.log(returnedTarget);

실행 결과


핵심 내용

Object.assign() 함수와 Object.create() 함수는 새로운 객체를 생성한다는 공통점이 있지만, 생성하는 방법이 다릅니다.

 

다음은 Object.assign() 함수를 사용하여 새로운 객체를 생성하고 속성의 값을 변경합니다.

const source = {
  a: 1,
  b: {
    c: 2
  }
};

const returnedTarget = Object.assign({}, source); 

console.log(source.b.c); // 2
console.log(returnedTarget.b.c); // 2

returnedTarget.b.c = 3

console.log(source.b.c); // 3
console.log(returnedTarget.b.c); // 3

returnedTarget.b.c의 값을 변경하면, source.b.c의 값도 변경됩니다.

 

이러한 이유는 Objet.assign() 함수는 얕은 복사본만 생성하므로 참조 영역을 공유합니다.

 

객체의 깊은 복사를 하기 위해서는 라이브러리를 사용하거나 별도의 코드를 작성해야 합니다.

 

다음은 Object.create() 함수를 사용하여 새로운 객체를 생성하고 속성의 값을 변경합니다.

const source = {
  a: 1,
  b: {
    c: 2
  }
};

const returnedTarget = Object.create(source); 

console.log(source.b.c); // 2
console.log(returnedTarget.b.c); // 2

returnedTarget.b.c = 3

console.log(source.b.c); // 3
console.log(returnedTarget.b.c); // 3

Object.create() 함수도 동일한 결과를 보여줍니다.

 

이러한 이유는 프로토타입 체인의 두 가지 규칙 때문입니다.

 

규칙 1. 자식 객체에서 속성 읽기

자식 객체에서 속성을 접근하려고 하면 JavaScript는 속성을 찾을 때까지 프로토타입 체인을 검색합니다.

 

규칙 2. 자식 객체에 속성 쓰기

변경하려는 속성을 가지는 객체를 찾은 다음에 속성을 설정합니다.

 

정리하자면, returnedTarget 객체에 존재하는 속성 'b'는 객체이며, 속성 'c'는 객체 'b'의 속성입니다.

 

즉, 'b'는 Object이며, returnedTarget와 source에 존재합니다.

 

JavaScript 엔진은 객체 'b'에 존재하는 속성 'c'를 변경했으므로 returnedTarget와 source에 존재하는 객체 'b'도 변경됩니다.

반응형

댓글