[모던 자바스크립트 Deep Dive] 11장 - 원시 값과 객체의 비교
🎉 원시 값과 객체의 비교
- 원시 타입의 값 : 변경 불가능한 값
- 변수에 할당하면 변수(확보된 메모리 공간)에 실제 값이 저장
- 값에 의한 전달 : 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달
- 객체(참조)타입의 값 : 변경 가능한 값
- 객체를 변수에 할당하면 변수(확보된 메모리 공간)에 참조 값이 저장
- 참조에 의한 전달 : 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달
😉 원시 값
- 원시 값은 변경 불가능한 읽기 전용 값, 변경할 수 없다.
- “원시 값은 변경 불가능하다” : 원시 값 자체를 변경할 수 없다는 것이지 변수 값을 변경할 수 없다는 것은 아니다.
- 참고) 상수 const !== 변경 불가능한 값 -> 재할당이 금지된 변수 (할당 된 객체는 변경 가능)
- 데이터의 신뢰성을 보장한다.
🐱🐉 값의 할당
새로운 원시 값을 재할당하면 메모리 공간에 저장되어 있는 재할당 이전의 원시 값을 변경하는 것이 아닌, 새로운 메모리 공간을 확보하고 재할당한 원시 값을 저장한 후, 변수를 새롭게 재할당된 값의 메모리 주소를 가르키는 것이다.
- 덮어 씌우기가 아닌 새로운 메모리 공간에 값을 저장한 후 메모리 주소를 변경하는 것 -> 값의 불변성
- 변수 값을 변경하기 위해 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 후, 변수가 참조하던 메모리 공간의 주소를 변경한다. 불변성은 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.
🐱🐉 문자열과 불변성
문자열
- 0개 이상의 문자로 이루워진 집합
- 1개의 문자는 2바이트의 메모리 공간에 저장
- 원시 타입이며 변경 불가능(문자열이 생성된 이후에는 변경할 수 없음을 의미)
- 유사배열객체이다.
- 유사객체 배열: 마치 배열처럼 인덱스 프로퍼티 값에 접근할 수 있고, length프로퍼티를 갖는 객체를 말한다.
var str = 'Hello';
str = 'world';
이 예시에서는 world가 할당될때 Hello를 수정하는 것이 아닌 새로운 문자열'world'의 메모리를 생성하고 식별자 str은 이것의 가르킨다.
메모리 상에는 'Hello'와 'world'둘다 있게 된다.
str[0] = 'S'; // 인덱스0번의 값을 재할당
console.log(str); // world 문자열은 원시 값이므로 변경을 할 수 없고, 이때 에러가 나지 않는다.
console.log(str[0]); // w 문자열은 유사배열임으로 비열과 유사하게 인덱스를 사용해 문자에 접근 가능
console.log(str.length); // 5 length도 가능
console.log(str.toUppercase()); //WORLD
🐱🐉 값에 의한 전달
- 변수에 원시 값을 갖는 변수를 할당하게 되면, 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달된다.
- 단, 다른 메모리 공간에 저장된 별개의 값이다.
var score = 80; //copy 변수에는 score변수의 값 80이 복사되어 할당된다.
var copy = score;
console.log(score, copy); //80 80
console.log(score === copy); //true
score = 100;
console.log(score, copy); //100 80
console.log(score === copy); //false 다른 메모리 공간에 저장된 별개의 값이라서 score를 변경하여도 copy의 값에 어떠한 영향도 주지 않는다.
변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달되기 때문에 변수와 같은 식별자는 값이 아니라 메모리 주소를 기억하고 있다.
두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해 값이 변경하더라도 서로 간섭할 수 없다.
😉 객체
🐱🐉변경 가능한 값
- 재할당 없이 객체를 직접 변경 가능 (프로퍼티를 동적 추가, 자체 삭제, 프로퍼티 값 갱신 가능)
var person = {
name: "Lee",
};
//프로퍼티 값 갱신
person.name = "Kim";
//프로퍼티 동적 생성
person.address = "Seoul";
console.log(person); //{name : "Kim", address : "Seoul";}
- 여러 개의 식별자가 하나의 객체를 공유할 수 있다.
- 할당한 변수가 기억하는 메모리의 주소를 통해 공간에 접근하여 참조값(reference value)에 접근한다.
- 참조값 : 생성된 객체가 저장된 메모리 공간의 주소, 그 자체
- 변수를 참조하면 메모리에 저장되어 있는 참조 값을 통해 실제 객체에 접근한다.
- 따라서 “변수는 객체를 참고 하고 있다” 또는 “변수는 객체를 가리키고 있다”라고 표현한다.
- 객체는 크기가 매우 클 수도 있고, 원시 값처럼 크키가 일정하지 않고, 프로퍼티 값이 객체일 수도 있어 복사하여 생성하는데 많은 비용이 든다. 즉 메모리 효율적 소비가 어렵고 성능이 나빠지는 단점이 있다.
- 원시 값과 다르게 여러개의 식별자가 하나의 객체를 공유할 수 있다.
🐱🐉 참조에 의한 전달
- 객체를 가르키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다.
var person1 = {
name: "lee",
};
var person2 = {
name: "lee",
};
var copy = person1; // 참조 값을 복사(얕은 복사)
var deepCopy = JSON.parse(JSON.stringfy(person1)); // 객체를 string 으로 변환 후 다시 parse 하여 새로운 객체와 참조 값을 만들어 할당
console.log(person1 === copy); // true -> 참조값이 가르키고 있는 객체가 같음
console.log(person1 === person2); // false -> 참조값이 각각 다른 객체를 가르키고 있음
console.log(person1.name === person2.name); // true -> 객체 내 원시 값이 같음 (메모리 주소는 다름)
Leave a comment