- 기본형 : number, string, boolean, null, undefined , Symbol
- 참조형 : Object, Array, function, Date, RegExp
기본형은 불변성 (기존에 값이 있는 주소에 위치한 해당 값을 변경 불가능한 것) ,
참조형은 가변성 (기존에 값이 있는 주소에 위치한 해당 값을 변경 가능한 것) 을 띈다.
불변성 가변성
- 변수 영역 : 변수와 상수를 구분 짓는 변경 가능성의 대상
- 데이터 영역 : 불변성 여부를 구분할 때의 변경 가능성의 대상( 불변성인 기본형은 데이터 영역의 값이 변경되지 않지만 가변성인 참조형은 데이터 영역의 값이 변경가능하다.)
기본적인 예시
var a = 'abc';
a = a + 'def';
var b = 5;
var c = 5;
b = 7;
- a,b,c, 전부 변수 영역에서 데이터 영역의 주소를 가지고 있다.
- a는 새로운 문자열을 만들어 이를 변수 a가 저장시킨다.
- b와 c는 모두 같은 값을 가르키고 있어 같은 주소를 가지고있다가 b의 값이 변경되면 일단 데이터 영역에 그 값을 가진 데이터영역이 있는지를 보고 없다면 새로운 데이터영역을 만들어 값을 생성해서 연결 짓는다.
=>
메모리에는 변수 영역과 데이터 영역이 있는데 같은 값이면 서로 다른 변수에서 이미 만들어진 그 주소에 있는 데이터를 재활용하나 바꾸고자 한다면 해당 값이 있는 데이터 영역을 찾고 없다면 새로 만들어내고 이 주소값을 저장
ex) 각 변수마다 숫자5를 할당하는 500개의 변수를 만들때, 매 공간하다 숫자 5를 할당시키면 8바이트씩 총 4000바이트가 필요한데, 만약 주소를 입력한다면 주소가 그보다 작은 2바이트정도라면 2*500 + 8 로 1008바이트만 필요하기 때문에
중복된 데이터에 대한 처리 효율이 높아진다.
ex)
var obj1 = {
a : 1,
b : 'bbb'
};
obj1.a = 2;
데이터 영역의 a가 참조하는 주소를 가진 값이 1에서 2로 변경되는 것을 알 수 있다. (가변)
참조 카운트가 0인 메모리주소는 가비지 컬렉터의 수거 대상이된다.
ex) 기존에 존재하던 배열이 문자열로 바뀔때
var obj1 = { c:10, d:'ddd'};
var obj2 = obj1;
b = 15;
obj2.c = 20;
var obj1 = { c:10, d:'ddd'};
var obj2 = obj1;
b = 15;
obj2 = {c : 20, d : 'ddd' };
참조형 데이터가
가변값
이라고 할때의 가변은 프로퍼티를 변경할때 적용
var user = {
name : 'msk',
gender : 'female'
};
var changeName = function (user,newName){
var newUser = user;
newUser.name = newName;
return newUser;
};
var user2 = changeName(user, 'kim');
console.log(user.name,user2.name)
console.log(user === user2);
기존의 user의 프로퍼티 값들도 변경이 된다.
해결방법
var user = {
name : 'msk',
gender : 'female'
};
var changeName = function (user,newName){
return {
name : newName,
gender : user.gender
};
};
var user2 = changeName(user, 'kim');
console.log(user.name,user2.name)
console.log(user === user2);
새로운 객체를 반환하도록 설정을 바꾸었다.
공통으로 포함되는 프로퍼티를 바꾸는 것이 아닌 그냥 어떤 값들을 얻어와서 새로운 객체를 만들어낸다.
처음 예시는 가게(user)에 돈 받으러와서 돈 받고 더달라고 맘대로 돈을 바꾸고(프로퍼티 변경) 두번째 예시는 가게에 돈 받으러와서 받을 돈만 받고 이제 상관 안하고 빠이빠이 하는 느낌일려나
객체의 프로퍼티 갯수에 상관없이 하드코딩 줄이기
기존 내용 복사 후 필요한 부분 값만 변경
var copyObject = function (target){
var result = {};
for( var prop in target){
result[prop] = target[prop];
}
return result;
};
var user = {
name : 'msk',
gender : 'female'
};
var user2 = copyObject(user);
user2.name = 'Kim';
console.log(user.name, user2.name);
console.log(user === user2);
코어 자바스크립트