Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

자바스크립트 스프레드 연산자로 객체 복제하는 방법 완벽 정리

복제(Clone)란 한 변수에 담긴 객체를 다른 변수로 복사하는 것을 의미합니다. 하지만 단순히 할당 연산자(=)를 사용해 객체를 복사하면 우리가 기대한 대로 동작하지 않습니다. 올바른 복제가 이루어지려면 한 변수의 값을 변경했을 때 다른 변수에는 아무런 영향을 주지 않아야 합니다. 그러나 할당 연산자를 사용하면 두 변수가 같은 객체를 참조하기 때문에, 한쪽에서 변경한 내용이 반드시 다른 쪽에도 반영됩니다. 이러한 단점을 보완하기 위해 ES6에서는 스프레드 연산자(...)를 제공합니다.

할당 연산자 사용 시 문제점

다음 예제는 단순 할당 연산자로 객체를 복사한 경우입니다. 원본 객체의 속성을 변경하자 복사본인 neworg까지 함께 변경되는 것을 확인할 수 있습니다.

<html>
<body>
<script>
    var org = {org1 : "Serveneedy", org2 : "Praveenlatha", org3 : "Redcross" };
    document.write(JSON.stringify("without change org :" + " "+ JSON.stringify(org)));
    var neworg = org;
    org.org1 = "gatesfoundation";
    document.write("</br>");
    document.write(JSON.stringify("with change org :" + " "+ JSON.stringify(org)));
    document.write("</br>");
    document.write(JSON.stringify("change also reflected in neworg :" +" "+JSON.stringify(neworg)));
</script>
</body>
</html>

실행 결과

"without change org : {\"org1\":\"Serveneedy\",\"org2\":\"Praveenlatha\",\"org3\":\"Redcross\"}"
"with change org : {\"org1\":\"gatesfoundation\",\"org2\":\"Praveenlatha\",\"org3\":\"Redcross\"}"
"change also reflected in neworg :{\"org1\":\"gatesfoundation\",\"org2\":\"Praveenlatha\",\"org3\":\"Redcross\"}"

위 결과에서 볼 수 있듯이 var neworg = org;는 새로운 객체를 만드는 것이 아니라 동일한 객체의 참조(주소)만 공유합니다. 따라서 org.org1의 값이 바뀌면 neworg의 값도 같이 바뀝니다.

스프레드 연산자를 사용한 객체 복제

다음 예제에서는 스프레드 연산자(...)를 사용해 객체를 복제합니다. 이 경우 원본 객체의 속성을 변경해도 복제된 객체에는 전혀 영향을 주지 않습니다.

<html>
<body>
<script>
    var org = {org1 : "Serveneedy", org2 : "Praveenlatha", org3 : "Redcross" };
    document.write(JSON.stringify("without change org :" + " "+ JSON.stringify(org)));
    var neworg = {...org};
    org.org1 = "gatesfoundation";
    document.write("</br>");
    document.write(JSON.stringify("with change org :" + " "+ JSON.stringify(org)));
    document.write("</br>");
    document.write(JSON.stringify("change also reflected in neworg" +" "+JSON.stringify(neworg)));
</script>
</body>
</html>

실행 결과

"without change org : {\"org1\":\"Serveneedy\",\"org2\":\"Praveenlatha\",\"org3\":\"Redcross\"}"
"with change org : {\"org1\":\"gatesfoundation\",\"org2\":\"Praveenlatha\",\"org3\":\"Redcross\"}"
"change also reflected in neworg : {\"org1\":\"Serveneedy\",\"org2\":\"Praveenlatha\",\"org3\":\"Redcross\"}"

{...org} 구문은 기존 객체의 모든 열거 가능한 속성을 새로운 객체로 펼쳐 담기 때문에, 완전히 독립된 복사본이 생성됩니다. 그래서 원본 orgorg1 값이 gatesfoundation으로 변경되었음에도 불구하고, 복제본 neworg는 여전히 초기 값 Serveneedy를 유지하고 있습니다.

주의할 점: 얕은 복사(Shallow Copy)

스프레드 연산자를 이용한 복제는 얕은 복사라는 점을 기억해야 합니다. 즉, 객체의 최상위 속성만 복사되며, 중첩된 객체나 배열이 있다면 해당 내부 객체는 여전히 참조로 공유됩니다. 중첩 구조까지 완전히 복제하려면 재귀적으로 복사하거나 structuredClone(), JSON.parse(JSON.stringify(obj)) 같은 깊은 복사 방법을 활용해야 합니다.