변경 불가능한 값(immutable value) vs 변경 가능한 값(mutable value)
- 원시 타입은 변경 불가능한 값이다.
- 객체 타입은 변경 가능한 값이다.
원시 타입
- 원시 타입은 값을 변경 할 수 없다. 하지만 재할당은 가능하다.(값이 변경되는것처럼 느껴지지만 변수가 가리키는 메모리 주소가 변경되는것이다.)
- string, number, bigint, boolean, undefined 등이 있다.
var str = 'hello';
str[0] = 's'; // Cannot assign to read only property '0' of string 'hello'
str = 'world'; // O 재할당 가능
참조 타입
- 참조 타입은 값을 변경 할 수 있다.
var me = {
name : 'Kim',
age : 25
}
var you = me;
console.log(me.age) // 25
you.age = 26
console.log(me.age) // 26
1. me객체의 참조 주소가 you객체에 복사되었다.
2. you객체와 me 객체는 같은 주소를 참조하고 있다.
3. you객체의 age값을 변경하면 me age값 또한 바뀐다.(같은 주소를 참조하고 있기 때문에)
헷갈리는 예제
var a = {
name : 'lee'
}
var b = a.name;
a.name = 'kim';
console.log(typeof a); // object
console.log(typeof b); // string
console.log(a.name); // kim
console.log(b) // lee
1. a객체는 객체 타입이지만 b에 값을 할당할 때
2. a객체의 참조 주소를 복사한게 아니라 a.name의 string값을 복사하여 넘겨주었다.
3. 즉 a객체의 프로퍼티 값을 변경 하더라도 b변수에는 영향이 없다.
불변 데이터 패턴
- 객체를 불변객체로 만들어 기존 객체의 프로퍼티 변경을 방지하는 패턴
1. Object.assign
// 문법
Object.assign(target, ...sources)
- 타겟 객체에 소스 객체의 프로퍼티를 복사한다.
- 기존 객체(소스 객체)를 변경하지 않고 객체를 복사 할 수 있다.
- 하지만 완전한 깊은복사(deep copy)를 지원하지 않는다(이유 : 객체 내부의 객체는 얕은복사(shallow copy)된다.)
var me = { age : 25 };
var assign = Object.assign({}, me);
console.log(me); // { age: 25 }
console.log(assign); // { age: 25 }
console.log(me == assign); // false 프로퍼티 값만 복사하고 참조 주소는 다르기 때문에
// 기존의 객체 프로퍼티는 변경되지 않고 프로퍼티 값을 복사하여 사용할 수 있다.
var name1 = { a : 'Kim' };
var name2 = { b : 'Lee' };
var name3 = { c : 'Park'};
var merge = Object.assign({}, name1, name2, name3);
console.log(name1); // { a: 'Kim' }
console.log(name2); // { b: 'Lee' }
console.log(name3); // { c: 'Park' }
console.log(merge); // { a: 'Kim', b: 'Lee', c: 'Park' }
const me = {
name : 'Kim',
hobby : {
game : 'LOL'
}
};
const me1 = Object.assign({}, me);
// me와 me1 객체는 참조 주소가 다르다.
console.log(me == me1) // false
me1.name = 'Lee'
console.log(me.name) // Kim
console.log(me1.name) // Lee
// 객체 내부의 객체는 얕은복사(shallow copy)가 되어서 둘중에 값이 변경되면 같이 값이 변한다.
// const로 선언되어 있어도 객체 프로퍼티의 값은 변경이 가능하다.
me.hobby.game = 'dota';
console.log(me.hobby.game); // dota
console.log(me1.hobby.game); // dota
'Javascript' 카테고리의 다른 글
| [Javascript] 호이스팅 (0) | 2021.07.03 |
|---|---|
| [Javascript] 함수(function) (0) | 2021.06.30 |
| [Javascript] 객체 (0) | 2021.06.21 |
| [Javascript] 데이터 타입 (0) | 2021.06.18 |
| 자잘한 용어 정리 (0) | 2021.06.09 |