ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 객체 복사하기(얕은·깊은) | ddalpange
    Javascript/ECMAScript 2009 (ES5) 2020. 2. 26. 19:35
    반응형

    [출처 : ddalpange.log]

    시작하기 전에

    # 예제 A

    const a = 1;
    const b = a;
    b = 2;
    console.log(a, b);

    # 예제 B

    const a = { p : 1 };
    const b = a;
    b.p = 2;
    console.log(a.p, b.p);

    자바스크립트는 불변형의 데이터를 선언할 때 포인터와 값 모두 생성하지만,

    오브젝트(배열)을 생성할 때에는 메모리 절약을 위해 포인터만 새로 할당할 뿐이다. 위 예제의 해석은

    - 예제 A는 b에 a를 복사하였다.
    - 예제 B는 b에 a를 대입하였다.

    단순히 대입연산자(=)를 통해 변수를 대입하는것과 얕은 복사는 엄연히 다르다.

    예제 B에서 b에 a를 복사하는 방법에는 다음과 같다.


    1. Object.assign()을 이용

    var object1 = {"name":AGAL, age:20};
    
    function cloneObject(obj) {
      return Object.assign({}, obj);
    }
    
    var obeject2 = cloneObject(object1);

    # Object.assign() 

    첫번째 인자로 들어오는 객체에 두번째 인자로 들어오는 객체의 프로퍼티들을 차례대로 덮어쓰기하여 반환하는 메소드이다.

     

    *여기서 주의할 점은 Object.assign()은 프로퍼티들에 대한 참조를 덮어쓰기하기 때문에,

     오브젝트 안에 오브젝트 또는 배열이 있을 경우 복사가 아닌 참조를 하게된다. 즉 객체를 얕은 복사(Shallow Copy)한다


    2. JSON 객체의 메소드를 이용

    function cloneObject(obj) {
      return JSON.parse(JSON.stringify(obj));
    }

    # JSON.stringify()

    자바스크립트 오브젝트를 스트링 포멧으로 변환하는 메소드이다.
    # JSON.parse()

    스트링 포멧을 자바스크립트 오브젝트로 변환하는 메소드이다.

     

    *스트링으로 변환하였다가 다시 오브젝트로 변환하기 때문에 이전 객체에 대한 참조가 없어지지만 JSON 메소드 자체가 성능면에서 다른 방법에 비해 굉장히 느리기 때문에 주의해야한다. 이 방법은 객체를 깊은 복사(Deep Copy)한다.


    3. 자바스크립트 재귀 사용

    function cloneObject(obj) {
        var clone = {};
        for(var i in obj) {
            if(typeof(obj[i])=="object" && obj[i] != null)
                clone[i] = cloneObject(obj[i]);
            else
                clone[i] = obj[i];
        }
        return clone;
    }

    오브젝트의 프로퍼티들을 순회하여 빈 오브젝트에 더한다.

    그 과정에서 원본 오브젝트의 프로퍼티가 오브젝트일 경우 재귀적으로 함수를 실행한다. 이 방법은 객체를 깊은 복사(Deep Copy)한다.

     

     


    4. Immutable.js 사용

    import { Map } from 'immutable';
    
    const map = Map({a : 1});
    const newMap = map;
    newMap.set('a', 2);
    console.log(map.get('a'));
    console.log(newMap.get('a'));

    페이스북에서 만든 오픈소스 라이브러리이다. Immutable.js를 쓰게된다면 Array, Map 모두 이뮤터블하게 쓸 수 있게된다.
    *객체의 내부 값을 변경해도 원본 객체의 값은 변화하지 않고 새로운 객체를 배출한다는 뜻이다.


    5. Spread 문법 사용 (ES6)

    function cloneObj(obj) {
    	return { ...obj }
    }

    Spread 구문을 사용하면 배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인수 (함수로 호출할 경우) 또는 요소 (배열 리터럴의 경우)로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있다. 즉 객체를 얕은 복사(Shallow Copy)한다.

     

    반응형

    댓글

Luster Sun