JS 데이터에는 원시자료형(primitive type), 참조 자료형(reference type) 타입이 있다.
변수에는 하나의 값이나 주소만 저장할수있다.
원시 자료형 (primitive type)
원시 자료형이 할당될 때, 변수에 할당할 때 값(value)을 저장하며, 하나의 데이터를 담는다.
number, string, boolean, undefined, null(엄밀하게는 객체다), symbol 등이 있다.
const stringA = 'a';
const number123 = 123;
const boolSample = true;
참조 자료형 (reference type)
원시 자료형이 아닌 모든 타입.
원시 자료형 데이터들의 집합이며, 변수에 할당할때 메모리 주소를 저장한다.
배열, 객체, 함수 등이 있다.
const로 선언한 변수에 Array.push로 값을 추가할 수 있는 이유는, 배열이 참조 자료형이기 때문이다. 값이 저장된 주소값을 할당하는것이다.
const myLanguage = 'js';
const languages = ['js','ts','c'];
myLanguage = 'c' // error
languages = 'ruby' // error
language.push('ruby') // ['js','ts','c','ruby'];
/* 발견한것 */
language.push = 'c++'
/*
이렇게 하면 어떻게 될까?
['js','ts','c','ruby', push:'c++']
위와같이 들어가지만, push라는 Array 메서드를 'c++'로 재정의 했기 때문에
이후 language.push('go')처럼 push 메서드를 사용할 수 없다.
이때 language는 Array이나( Array.isArray(language) ),
push:'c++'를 카운트하지않는다.
language.pop()을 하면, push:'c++'이 아닌 'ruby'가 출력된다.
*/
얕은복사 (shallow copy)
참조값을 복사한다. 같은 데이터를 바라보고 있기 때문에, 데이터를 변경하면 원시데이터도 바뀐다.
const origin = {key : 30};
const copyOrigin = origin;
copyOrigin.key = 1;
console.log(origin.key) // 1
깊은복사 (deep copy)
값 자체를 복사하여 다른 메모리 주소를 할당한다. JS의 원시형 데이터는 깊은복사를 한다.
원시 데이터와 연결(참조)이 완전히 끊긴 새로운 데이터이다.
let original = 35;
let copyOriginal = original;
copyOriginal = 1;
console.log(original) // 35
console.log(copyOriginal) // 1
참조형 데이터를 SpreadOperator(...), 혹은 Object.assign( { }, 원본) 를 이용해 복사를 하고, 서로 비교하면 false 가 나온다.
서로 참조 주소가 다르다는걸 알수있다.
const data = {
name:'rumi',
isE : true,
book:{
0:'테스트',
1:'JS 원리'
}
}
const copyData = data;
console.log(data === copyData); // true
const spreadData = {...data};
console.log(data === spreadData; //false
const objAssignData = Object.assign({}, data);
console.log(data === objAssignData); // false
하지만 SpreadOperator(...), 혹은 Object.assign( { }, 원본) 은 1depth 밖에 깊은복사되지 않는다.
참조형 내부의 참조형데이터는 얕은복사가 된다.
const data = {
name:'rumi',
isE : true,
book:{
0:'테스트',
1:'JS 원리'
}
}
const spreadData = {...data};
spreadData.book[0] = 'test'; // 복사한 데이터를 변경했더니
console.log(data.book[0]) // 원본 데이터가 test로 바뀐다.
따라서 완전한 깊은복사를 하려면 JSON.parse(JSON.stringify(data))를 사용하거나, lodash 라이브러리를 사용한다.
* JSON.parse(JSON.stringify()) 방법은 함수에 대한 깊은복사는 수행하지않는다.
'[IT] 프로덕트 개발 > Javascript - 자바스크립트' 카테고리의 다른 글
[Javascript] 자주쓰는 JS 메서드 정리하기 (2) | 2022.08.31 |
---|---|
[Javascript] map 메서드 그리고 reduce (3) | 2022.08.31 |
[Javascript] Nullish coalescing operator / 널리쉬 병합 논리 연산자 (2) | 2022.05.21 |
[Javascript] for, forEach, for in, for of, map으로 반복 수행하기 (2) | 2022.05.01 |
[Javascript] Object.assign, spread 연산자로 새로운 배열, 새로운 object를 만들기 (2) | 2022.05.01 |