Javascript mutation assignment
2024년 02월 02일object, array의 const
const dugi = {
city: "Seoul",
age: 30
}
dugi.city = "Sydney";
console.log(dugi.city) //"Sydney"
dugi.hobby = "Running"
console.log(dugi) //{city: 'Sydney', age: 30, hobby: 'Running'}
위 코드에서 const로 object를 만들었다. 하지만 내부의 프로퍼티의 값을 변경할 수 있다. hobby라는 프로퍼티를 추가하는 것도 가능하다.
const fruits = ["banana", "apple"];
fruits.pop()
fruits.pop()
console.log(fruits); // []
fruits.push("melon");
const로 만든 array가 있다. const로 만들었지만 array 역시 element를 추가하거나 삭제하는 것이 가능하다.
왜 그럴까? 이해하기 위해서 mutation과 assignment 개념을 알아야한다.
mutation vs assignment
assignment
처음 코딩을 배울 때 변수를 만드는 걸 이렇게 이해했다. 변수라는 빈 공간을 만들고 거기안에 데이터를 넣는거라고. 그리고 let
으로 만든 변수는 안에 내용물을 바꿀 수 있고 const
는 바꿀 수 없는 거라고. 코드를 쓰는 형태 자체도 이렇게 생각하게 만든다. const name = "dugi";
이런식이니까
근데 사실 이건 틀린 멘탈 모델이고, 실제로는 이렇게 된다. object(array도 object 데이터 타입이므로 마찬가지)가 별도로 만들어지고 변수 dugi와 연결(assign)된다.
const는 이 연결은 바꿀 수 없고, let은 바꿀 수 있다. assign을 변경할 수 없으면 const 바꿀 수 있으면 let이다.
mutation
반대로 위의 예시에서 처럼 const 여도 { }
안의 내용은 변경이 가능하다. 마찬가지로 [ ]
안의 내용도 변경이 가능하다. 왜 그럴까.
dugi
와 연결된 { }
는 다른 { }
로 연결이 바뀌지 않았고, { }
의 key,value만 바뀌었기 때문이다. 이 { }
안의 내용을 변경하는 것을 mutation이라고 한다. key:value쌍을 추가할수도 있고, 특정 key의 value만 바꿀 수도 있다. array라면 요소를 추가하거나 삭제할 수 있다.
const dugi = {
city: "Seoul",
age: 30
};
dugi.city = "Jeju"; //mutation
dugi.age = 40; //mutation
하지만 아래와 같은 변경은 불가능하다. 기존에 있던 { }
의 내용을 바꾸는 게 아니라, 아예 새로운 { }
를 만들어 할당(assgin)하려는 코드이기 때문이다.
dugi = {
city: "Jeju",
age: 40
}
//Uncaught TypeError: Assignment to constant variable.
object안의 object
그럼 이건 어떨까.
const dugi = {
address : {
city: "Seoul"
},
age: 30
};
const summer = {
address : dugi.address,
age: 31
}
summer.address.city = "Jeju"
console.log(dugi.address); //{city: "Jeju"}
summer
의 address.city
를 바꿨는데 왜 dugi
의 address.city
가 바뀌었을까?
자바스크립트의 객체 ( { }
로 감싸진 단위) 하나하나는 별도로 존재한다.
summer의 address를 dugi.address로 할당했기 때문에 summer.address는 dugi.address와 같은 {city: "Seoul"}
객체에 연결되어 있다. 그렇기 때문에 어디서든 그 객체의 key value를 변경(mutation)하면 summer.address dugi.address 모두에서 변경이 된다.
얕은 복사
객체를 아래처럼 만들면 최초 깊이의 프로퍼티는 값만 가져와서 공유가 되지만 그 이상 깊이의 내부 객체는 원본을 공유한다. 그렇기에 변경시 원본에 영향을 끼친다.
const dugi = {
address : {
city: "Seoul"
},
age: 30
};
const summer = { ...dugi };
summer.age = 40;
summer.address.city = "Jeju";
console.log(dugi);
//{ address: {city: "Jeju", age: 30};
깊은 복사
복사한 객체에서 변경을 했는데, 원래의 객체는 변경을 원하지 않을 경우가 있다. 그럴때는 이런 방법이 있다.
1 Object.freeze
메서드 사용
const summer = {};
summer.address = Object.freeze(dugi.address);
summer.address.city = "Jeju";
console.log(dugi.address.city); //Seoul
2 JSON.parse(JSON.stringify())
사용
const summer = {};
summer.address = JSON.parse(JSON.stringify(dugi.address));
summer.address.city = "Jeju";
console.log(dugi.address.city); //Seoul
정리
let
const
는 assign을 변경할 수 있는지 없는지에 영향을 끼친다. const는 assign 변경이 불가하다.const
라도 연결된 객체를 유지한테 객체 내부의 값을 변경, 추가, 삭제할 수 있다.- 객체는
{ }
마다 별도의 객체가 생성되는 것이라서 객체를 복사할 때 객체 내부의 객체는 실제로는 복사되는 것이 아니라 원본에 연결(assign)된다.
TAGS
JAVASCRIPT