(1) Primitive: 원시 데이터 타입 (string, number, bigint, boolean, undefined, symbol, null) => 모든 원시값은 불변하여 변형할 수 없음 (immutable)
원시값을 교체할 수는 있지만, 직접 변형할 수는 없음
(2) Object: 객체 (Object, Array, Function)
-> 할당된 변수를 조작하는 것은 사실 객체 자체를 조작하는 것이 아닌, 해당 객체의 참조를 조작하는 것임
(mutable)
// 문자열 메서드는 문자열을 변형하지 않음
let bar = "baz";
console.log(bar); // baz
bar.toUpperCase();
console.log(bar); // baz
// 할당은 원시 값에 새로운 값을 부여 (변형이 아님)
bar = bar.toUpperCase(); // BAZ
let a = 1
let b = 1
console.log(a, b, a===b) // 1 1 true
// 배열 메소드는 배열을 변형함
let foo = [];
console.log(foo); // []
foo.push("plugh");
console.log(foo); // ["plugh"]
let c = {name: 'chaelin'}
let d = {name: 'chaelin'}
console.log(c, d, c===d)
# { name: 'chaelin' } { name: 'chaelin' } false
> 원시 데이터 타입은 값이 같으면 같은 주소를 가리키지만
객체는 그렇지 않음
let a = {name: 'chaelin'}
let b = {name: 'chaelin'}
let c = a
c.name = 'chae'
얕은 복사란 객체를 복사할 때 기존 값과 복사된 값이 같은 참조를 가리키고 있는 것을 말함 (객체 안에 객체가 있을 경우 한 개의 객체라도 기존 변수의 객체를 참조하고 있다면 이를 얕은 복사라고 함)
const original = ['a',2,true,4,"hi"];
const copy = original.slice();
console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
copy.push(10);
console.log(JSON.stringify(original) === JSON.stringify(copy)); // false
console.log(original); // [ 'a', 2, true, 4, 'hi' ]
console.log(copy); // [ 'a', 2, true, 4, 'hi', 10 ]
얕은 복사, 배열안에 들어있는 원시값은 기본적으로 깊은 복사임
const original = [
[1, 1, 1, 1],
[0, 0, 0, 0],
[2, 2, 2, 2],
[3, 3, 3, 3],
];
const copy = original.slice();
console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
// 복사된 배열에만 변경과 추가.
copy[0][0] = 99;
copy[2].push(98);
console.log(JSON.stringify(original) === JSON.stringify(copy)); // true
console.log(original);
// [ [ 99, 1, 1, 1 ], [ 0, 0, 0, 0 ], [ 2, 2, 2, 2, 98 ], [ 3, 3, 3, 3 ] ]출력
console.log(copy);
// [ [ 99, 1, 1, 1 ], [ 0, 0, 0, 0 ], [ 2, 2, 2, 2, 98 ], [ 3, 3, 3, 3 ] ]출력
배열안에 배열은 얕은 복사가 된 것임
let a = {name: 'chaelin'}
let b = Object.assign({}, a)
b.name = 'chae'
console.log(a, b, a===b)
# { name: 'chaelin' } { name: 'chae' } false
let a = {name: 'chaelin', score: [10, 20] }
let b = Object.assign({}, a)
let a = {name: 'chaelin', score: [10, 20] }
let b = Object.assign({}, a)
b.score = b.score.concat()
let a = {name: 'chaelin', score: [10, 20] }
let b = Object.assign({}, a)
b.score = b.score.concat()
b.score.push(3)
console.log(a === b, a.score === b.score)
# false false
const fruitOne = ['apple', 'banana'];
const fruitTwo = ['grape', 'peach'];
// ES6 spread 연산사 활용 방법
const fruitAll = [...fruitOne, ...fruitTwo];
console.log(fruitAll); // ['apple', 'banana', 'grape', 'peach']
깊은 복사된 객체는 객체 안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊어진 객체를 말함
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
arr: [1, 2, [3, 4]],
};
const copy = JSON.parse(JSON.stringify(object));
copy.number.one = 3;
copy.arr[2].push(5);
console.log(object === copy); // false
console.log(object.number.one === copy.number.one); // false
console.log(object.arr === copy.arr); // false
console.log(object); // { a: 'a', number: { one: 1, two: 2 }, arr: [ 1, 2, [ 3, 4 ] ] }
console.log(copy); // { a: 'a', number: { one: 3, two: 2 }, arr: [ 1, 2, [ 3, 4, 5 ] ] }
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
arr: [1, 2, [3, 4]],
};
function deepCopy(object) {
if (object === null || typeof object !== "object") {
return object;
}
// 객체인지 배열인지 판단
const copy = Array.isArray(object) ? [] : {};
for (let key of Object.keys(object)) {
copy[key] = deepCopy(object[key]);
}
return copy;
}
const copy = deepCopy(object);
copy.number.one = 3;
copy.arr[2].push(5);
console.log(object === copy); // false
console.log(object.number.one === copy.number.one); // false
console.log(object.arr === copy.arr); // false
console.log(object); // { a: 'a', number: { one: 1, two: 2 }, arr: [ 1, 2, [ 3, 4 ] ] }
console.log(copy); // { a: 'a', number: { one: 3, two: 2 }, arr: [ 1, 2, [ 3, 4, 5 ] ] }
const deepCopy = require("lodash.clonedeep")
const object = {
a: "a",
number: {
one: 1,
two: 2,
},
arr: [1, 2, [3, 4]],
};
const copy = deepCopy(object);
copy.number.one = 3;
copy.arr[2].push(5);
console.log(object === copy); // false
console.log(object.number.one === copy.number.one); // false
console.log(object.arr === copy.arr); // false
console.log(object); // { a: 'a', number: { one: 1, two: 2 }, arr: [ 1, 2, [ 3, 4 ] ] }
console.log(copy); // { a: 'a', number: { one: 3, two: 2 }, arr: [ 1, 2, [ 3, 4, 5 ] ] }
https://developer.mozilla.org/ko/docs/Glossary/Primitive
https://pythontutor.com/
https://bbangson.tistory.com/78
Image by Ylanite Koppens from Pixabay