티스토리 뷰

목차

1-5-1 불변 객체를 만드는 간단한 방법

1-5-2 얕은 복사와 깊은 복사

 

 

1-5-1 불변 객체를 만드는 간단한 방법

객체의 가변성에 따른 문제점

var user = {
    name: 'Timmy',
    gender: 'male'
};


var changeName = function (user, newName) {
    var newUser = user;
    newUser.name = newName;
    return newUser;
};

var user2 = changeName(user, 'Tim');

console.log(user.name, user2.name); //Tim Tim
console.log(user === user2); //true

changeName 함수에 인자로 user 객체를 넘겨주고 newUser로 바로 할당하면

객체 user와 newUser는 참조관계가 성립한다.

그러므로 한쪽의 객체내부 값을 바꾸면 다른쪽의 객체에서도 똑같이 값이 변한다.

 

값으로 전달받은 객체에 변경을 가하더라도 원본 객체는 변하지 않아야하는 경우가 존재한다.

이럴 때 불변 객체가 필요하다

 

 

객체의 가변성에 따른 문제점을 해결 방법

var user = {
    name: 'Timmy',
    gender: 'male'
};


var changeName = function (user, newName) {
    return {
        name: newName,
        gender: user.gender
    }
};

var user2 = changeName(user, 'Tim');

console.log(user.name, user2.name); //Timmy Tim
console.log(user === user2); //false

console.log(user.gender === user2.gender); //true //미흡한 부분

changeName 함수에 새로운 객체를 반환하도록 했다.

user와 user2는 다른 객체지만, 새 객체를 만들면서 변경할 필요가 없는 기존 객체 프로퍼티(gender)를 하드코딩 했다.

이런 방식으로 변경해야 할 정보가 많으면 사용자가 번거로워질 것이다.

이런 방법보다는 대상 객체의 프로퍼티 개수에 상관 없이 모든 프로퍼티를 복사하는 함수를 만드는 게 더 좋다.

 

 

기존 정보를 복사해서 새로운 객체를 반환하는 함수(얕은 복사)

var copyObject = function (target) { // parameter: object
    var result = {};
    for (var prop in target) { // 
        result[prop] = target[prop];
    }
    return result;
};

var user = {
    name: 'Tim',
    languages: ['html', 'css', 'js']
};

var user2 = copyObject(user);
user2.name = 'Lee';

console.log(user === user2); //false
console.log(user.name, user2.name); //Tim Lee
console.log(user.languages === user2.languages); //true

 맨마지막 줄에서 얕은 복사이기 때문에 객체안의 객체는 복사되지 않고 참조하고 있는것을 알 수 있다.

 

1-5-2 얕은 복사와 깊은 복사

얕은 복사(shallow copy) : 바로 아래 단계의 값만 복사하는 방법

깊은 복사(deep copy): 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법

 

var copyObject = function (target) { // parameter: object
    var result = {};
    for (var prop in target) { // 
        result[prop] = target[prop];
    }
    return result;
};

var user = {
    name: 'Tim',
    languages: {
        first: 'html',
        second: 'css',
        thirt: 'js'
    }
};

var user2 = copyObject(user);
user2.languages = copyObject(user.languages);

user.languages.first = 'HTML';
console.log(user.languages.first, user2.languages.first); //HTML html

user2.languages.second = '';
console.log(user.languages.second, user2.languages.second); // css 없음
console.log(user.languages.second === user2.languages.second); //false

어떤 객체를 복사할 때 객체 내부의 모든 값을 복사해서 새로운 데이터를 만들때,

객체 프로퍼티 중에서 값이 기본형 데이터(primitive type data)일 경우에는 복사가 된다.

하지만 참조형 데이터(reference type data)는 다시 내부의 프로퍼티를 복사해야 한다.

이러한 과정을 참조형 데이터가 있을 때마다 항상 재귀적으로 수행해야 Deep Copy가 된다.

 

객체의 깊은 복사를 수행하는 범용 함수

var copyObjDeeply = function(target) {
    var result = {};
    if (typeof target === 'object' && target !== null) { // target이 객체인 경우와 null인 아닌경우(null도 'obj'이기 때문)
        for (var prop in target) { //프로퍼티 순회하여
            result[prop] = copyObjDeeply(target[prop]); // 함수 재귀호출
        }
    } else { //객체가 아닌 경우에는 
        result = target; //target값 그대로 지정
    }
    return result;
}

//깊은 복사 결과 확인
var obj = {
    a: 1,
    b: {
        c: null,
        d: [1, 2]
    }
};
var obj2 = copyObjDeeply(obj);

obj2.a = 3;
obj2.b.c = 4;
obj.b.d[1] = 3;

console.log(obj);  //{ a: 1 b: {c: null, d: [1, 3]} }
console.log(obj2); //{ a: 3 b: {c: 4, d: [1, 2] }

아래에 코드 확인하기

https://pythontutor.com/visualize.html#mode=edit

 

Python Tutor - Visualize Python, Java, JavaScript, C, C++, Ruby code execution

Write code in Python 3.6 Java 8 JavaScript ES6 C (gcc 9.3, C17 + GNU extensions) C++ (g++ 9.3, C++20 + GNU extensions) ------ [unsupported] Python 2.7 [unsupported] C (gcc 4.8, C11) [unsupported] C++ (g++ 4.8, C++11) [unsupported] TypeScript 1.4 [unsupport

pythontutor.com

 

JSON을 활용한 간단한 깊은 복사

var copyObjViaJSON = function (target) {
    return JSON.parse(JSON.stringify(target));
};

var obj = {
    a: 1,
    b: {
        c: null,
        d: [1, 2],
        func1: function() {console.log(3);},
    },
    func2: function() {console.log(4);}
};

var obj2 = copyObjViaJSON(obj);

obj2.a = 3;
obj2.b.c = 4;
obj.b.d[1] = 4;

console.log(obj); // { a: 1 b: { c: null, d: [1, 4], func1: ƒ () }, func2: ƒ ()}
console.log(obj2); // { a: 3, b: {c: 4, d: [1, 2]} }

 

댓글
다크모드
Document description javascript psychology
더보기 ,제목1 태그 호버