최근 객체를 복사하여 값을 변경해주는 경우가 있었는데, 원본도 같이 변경되기에 제대로 알아보기 위해 이글을 작성하였다
const data = req.body;
data.password = await bcrypt.hash(req.body.password, 10);
예상한 것은 data의 객체의 password 만 변경되는 거였는데 req.body의 값도 변경되는 것을 보아 참조되는 객체는 주소가 복사가 된다는 의심이 생겼다.
결론은 내 생각이 맞다. 참조값은 주소를 복사한다.
자바스크립트에서는 값이 원시값과 참조값으로 나누어진다.
원시값은 값을 복사할때 메모리를 할당하기에 원본의 영향이 가지 않는다.
하지만 참조값은 변수가 객체의 주소를 가리키게 되어 같은 원본과 같은 주소를 사용한다.
그렇다면 어떻게 주소와 상관없이 복사할 수 있을까?
깊은 복사를 해주면 된다.
const obj = {
a: 1,
b: {
c: 2,
},
};
function copyObj(obj) {
const result = {};
// for ( key in val) 문법사용
for (let key in obj) {
if (typeof obj[key] === 'object') {
result[key] = copyObj(obj[key]);
} else {
result[key] = obj[key];
}
}
return result;
}
const copiedObj = copyObj(obj);
copiedObj.b.c = 3
obj.b.c === copiedObj.b.c //false
객체를 json으로 바꾸어 주는 동안 주소와의 연결이 끝기기에 json 값을 복사한후 다시 JSON.parse()
이용하여 객체로 만들어주면 된다.
const obj = {
a: 1,
b: {
c: 2,
},
};
const copiedObj = JSON.parse(JSON.stringify(obj));
copiedObj.b.c = 3
obj.b.c === copiedObj.b.c //false
Object.assign은 첫번째 요소로 들어온 객체에 다음인자로 들어온 객체를 복사해준다.
const obj = {
a: 1,
b: {
c: 2,
},
};
const copiedObj = Object.assign({}, obj);
copiedObj.b.c = 3
obj === copiedObj // false
obj.b.c === copiedObj.b.c // true
const obj = {
a: 1,
b: {
c: 2,
},
};
const copiedObj = {...obj}
copiedObj.b.c = 3
obj === copiedObj // false
obj.b.c === copiedObj.b.c // true