// lodash의 cloneDeep을 사용한 깊은 복사
const o = {x: {y:1}};
const {cloneDeep} from 'lodash';
const c2 = cloneDeep(o)
console.log(c1 === o) //false
console.log(c1.x === o.x) // false
const v = 1;
const c1 = v;
console.log(c1 === v)
obj1과 obj2는 다른 주소를 가지게 된다.
실제로 웹 개발을 하다보면 lodash 모듈은 흔히 사용되며, 가장 손쉽게 객체의 깊은 복사를 해결하는 방법이라 할 수 있다.
const o = {x: {y:1}};
const c1 = {...o};
console.log(c1 === o) //false
console.log(c1.x === o.x) // true
const o = {x:1}
const c1 = o;
console.log(c1 === v) //true
객체를 직접 대입하는 경우 참조에 의한 할당이 이루어지므로 둘은 같은 데이터(주소)를 가지고 있다.
객체
와 원시타입
의 근본적인 차이중 하나는 객체는 참조에 의해 저장되고 복사
된다는 것이다.
원시값(문자열, 숫자, 불린 값)은 '값 그대로' 저장, 할당되고 복사되는 반면에 말이다.
let user = {
name : "John"
};
변수엔 객체 그대로 저장 되는 것이 아니라, 객체가 저장되어있는 메모리 주소인 객체의 참조값이 저장 된다. 👓
let user = { name: 'John' };
let user2 = { name: 'John' };
let admin = user;
admin.name = 'Pete';
console.log(user == user2) // false
console.log(user.name); // Pete
객체가 할당된 변수를 복사할 땐 객체의 참조 값이 복사되고 객체의 값이 복사되지 않는다.
let a = {};
let b = a; // 참조에 의한 복사
alert( a == b ); // true, 두 변수는 같은 객체를 참조합니다.
alert( a === b ); // true
두 변수는 같은 객체를 참조 하기때문에 동등연산자를 사용할 시 true라는 값을 반환합니다
let a = {};
let b = {}; // 독립된 두 객체
alert( a == b ); // false
반면, 독립된 두 객체에 대해서는 가지고 있는 주소값이 다르므로 false라는 값을 반환하게 된다.
let user = {
name: "John",
age: 30
};
let clone = {}; // 새로운 빈 객체
// 빈 객체에 user 프로퍼티 전부를 복사해 넣습니다.
for (let key in user) {
clone[key] = user[key];
}
// 이제 clone은 완전히 독립적인 복제본이 되었습니다.
clone.name = "Pete"; // clone의 데이터를 변경합니다.
alert( user.name ); // 기존 객체에는 여전히 John이 있습니다.
let user = {
name: "John",
age: 30
};
let clone = Object.assign({}. user);
여러 객체를 병합할 경우에도 사용 할 수 있다.
let user = { name: "John" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };
// permissions1과 permissions2의 프로퍼티를 user로 복사합니다.
Object.assign(user, permissions1, permissions2);
// now user = { name: "John", canView: true, canEdit: true }
단 동일한 이름을 가진 프라퍼티가 있을 경우 오버라이딩되어 값이 덮어씌워짐
또한 이때 얕은 복사본은 중첩 객체를 처리하지 못한다
var a = [1,2,3]
var b = [1,2,3]
var c = "1,2,3"
console.log(a==b)
console.log(a==c)
console.log(a===b)
a와 b의 경우 원시값이 아닌 둘다 배열의 참조값을 가져와 비교함으로써 당연히! false
a==c의 경우 ===(Identity / strict equality) 가 아닌 ==(Equality) 를 사용했을때
Equality (==) (source)
The equality operator converts the operands if they are not of the same type,
then applies strict comparison. If both operands are objects, then JavaScript
compares internal references which are equal when operands refer to the same object in memory.
비교하는 두 대상이 다른 형태를 가지고 있을 경우 자바스크립트에서 두 형태를 같게 변형시킨후 비교하게 되어 a.toString === c 와 같이 비교되므로써 결과는 true가 나오게 됨
console.log(a==b) // false
console.log(a==c) // true
console.log(a===b)// false
https://javascript.info/object-copy
[JavaScript] 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)