모던 자바 스크립트 Deep Dive 를 읽고 정리한 글 입니다.
원시 타입 | 객체 타입 |
변경 불가능한 값 | 변경 가능한 값 |
변수에 할당하면 변수에 실제 값 저장 | 변수에 할당하면 변수에 참조 값 저장 |
원시 값 할당 변수 참조 -> 메모리에 저장되어 있는 원시 값 접근 |
객체 할 변수 참조 -> 메모리에 저장된 참조 값으로 실제 객체 접근 |
"변수는 ~ 값을 갖는다" "변수의 값은 ~ 이다" |
"변수는 객체를 참조하고 있다" "변수는 객체를 가리키고 있다" |
변수를 다른 변수에 할당 => 원본의 원시 값이 복사되어 전달 = 값에 의한 전달 |
변수를 다른 변수에 할당 => 원본의 참조 값이 복사되어 전달 = 참조에 의한 전달 |
원시 값을 가진 변수 값 변경 -> 재할당 |
객체를 할당한 변수 값 변경 -> 직접 변경 가능 |
String (문자) Number (숫자) Boolean (참,거짓) Null Undefined Biglnt Symbol |
Object (객체) Array (배열) Function (함수 |
변수
하나의 값을 저장하기 위해 확보한 메모리 공간
메모리 공간을 식별하기 위해 붙인 이름
언제든지 재할당을 통해 변수값 교체 가능
상수
재할당이 금지된 변수
단 한 번만 할당이 허용 되므로 변수 값 교체 불가
값
변수에 저장된 데이터
표현식이 평가되어 생성된 결과
11. 1 원시 값
변경 불가능한 값
한번 생성된 원시 값 = 읽기 전용 값
변경 불가능한 것은 변수가 아니라 값에 대한 진술
데이터의 신뢰성 보장
상수와 변경 불가능한 값은 다름
불변성
변수 값을 변경하기 위해 원시값을 재할당 / 원시 값을 할당한 변수에 새로운 원시 값 재할당
-> 새로운 메모리 공간 확보, 재할당한 원시 값 저장
(메모리 공간에 저장되어 있는 재할당 이전의 원시값 변경 X)
-> 변수가 참조하던 메모리 공간의 주소 변경 - 변수는 새롭게 재할당한 원시 값
불변성을 갖는 원시 값을 할당한 변수는 재할당 이외의 변수 값을 변경할 수 있는 방법이 없음
문자열과 불변성
문자열
0개 이상의 문자로 이루어진 집합
1개의 문자는 2바이트의 메모리 공간에 저장
몇개의 문자로 이루어졌는지에 따라 필요한 메모리 공간의 크기 결정
유사 배열 객체
이터러블
- 1개의 문자 : 2바이트
- 10개의 문자 : 10바이트
숫자 값
1과 1000000 모두 동일한 8파이트 필요
var str = 'Hello';
str = 'world';
첫 번째 문 실행 - 문자열 'Hello' 생성, 식별자 str은 문자열 'Hello'가 저장된 메모리 공간의 첫 번째 메모리 셀 주소 나타냄
두번째 문 실행 - 새로운 문자열 'world' 메모리에 생성, 식별자 str은 이것을 나타냄.
문자열 'Hello', 'world' 모두 메모리에 존재
식별자 str은 문자열 'Hello'를 가리키고 있다가 문자열 'world'를 가리키도록 변경
var str = 'string';
// 문자열은 유사배열, 인덱스를 사용하여 각 문자에 접근 가능
// 그러나 원사 값이므로 변경 불가, 에러 발생하지 않음
str[0] = 'S'; // 이미 생성된 문자열의 일부 문자 변경도 반영 X
console.log(str); // => string
유사 배열 객체
배열처럼 인덱스로 프로퍼티 값에 접근 가능
length 프로퍼티를 갖는 객체
for문으로 순회 가능
값에 의한 전달 = 공유에 의한 전달
변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달
두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값
어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없음
변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달
변수와 같은 식별자는 값이 아니라 메모리 주소를 기억
전달된 메모리 주소를 통해 메모리 공간에 접근하면 값 참조 가능
var score = 80;
// copy 변수에는 score 변수의 값 80이 복사되어 할당
var copy = score;
console.log(score, copy); // => 80 80
console.log(cxore === copy); // => true
// score 변수의 값을 변경해도 copy 변수의 값에는 어떠한 영향을 주지 않음
score = 100;
console.log(score, copy); // => 100 80
console.log(cxore === copy); // => false
11. 2 객체
자바스크립트 객체의 관리 방식
클래스 없이 객체 생성 가능
객체 생성 후에도 동적으로 프로퍼티와 메서드 추가 가능
클래스 기반 객체 지향 프로그래밍 언어의 객체보다 비효율적
여러 개의 식별자가 하나의 객체 공유 가능
메모리에 저장된 객체 직접 수정 가능하나 재할당하지 않은 경우 객체를 할당한 변수의 참조 값은 변경되지 않음.
변경 가능한 값
객체를 할당한 변수에는 생성된 객체가 실제로 저장된 메모리 공간의 주소 저장
변수는 이 참조 값을 통해 객체에 접근 가능
// 할당이 이뤄지는 시점에 객체 리터럴이 해석 -> 객체 생성
var person = {
name: 'Lee'
};
// person 변수에 저장되어 있는 참조 값으로 실제 객체에 접근
console.log(person); // => {name: "Lee"}
재할당 없이 프로퍼티 동적 추가, 프로퍼티 값 갱신, 프로퍼티 삭제 가능
var person = {
name: 'Lee'
};
// 프로퍼티 값 갱신
person.name = 'Kim';
// 프로퍼티 동적 생성
person.address = 'Seoul';
console.log(person); // => {name: "Kim, address: "Seoul"}
참조 값
생성된 객체가 저장된 메모리 공간의 주소
참조에 의한 전달
객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달
var person = {
name: 'Lee'
};
//얕은 복사
var copy = person;
두개의 식별자가 하나의 객체를 공유
원본과 사본은 저장된 메모리 주소는 다르지만 동일한 참조 값을 가짐, 동일 객체를 가리킴
한쪽의 객체를 변경(새로운 객체 재할당이 아니라 객체의 프로퍼티 값 변경, 추가 삭제)하면 영향 받음
var person = {
name: 'Lee'
];
// 참조 값 얕은 복사
// copy, person 동일 참조 값
var copy = person;
//copy, person 동일 객체 참조
console.log( copy === person); // => true
// copy를 통해 객체 변경
copy.name = 'Kim';
//person을 통해 객체 변경
person.address = 'Seoul';
//copy, person 동일 객체 - 변경 시 서로 영향
console.log(person); // {name: "Kim", address: "Seoul"}
console.log(copy); // {name: "Kim", address: "Seoul"}
얕은 복사 | 깊은 복사 |
객체를 프로퍼티 값으로 갖는 객체를 한단계까지 복사 |
객체를 프로퍼티 값으로 갖는 객체를 중첩되어 있는 객체까지 모두 복사 |
객체에 중첩되어 있는 객체 - 참조 값 복사 |
객체에 중첩되어 있는 객체 - 중첩 객체 모두 복사하여 원시 값처럼 완전한 복사본 |
객체를 할당한 변수를 다른 변수에 할당 | 원시 값을 할당한 변수를 다른 변수에 할당 |
생성된 객체는 원본과 다른 객체 원본과 복사본은 참조 값이 다른 객체 |
const o = { x: { y: 1} };
// 얕은 복사
const c1 = { ... o};
consloe.log(c1 === o); //=> false
consloe.log(c1.x === o.x); //=> true
// 깊은 복사
const c2 = _.cloneDeep(o);
consloe.log(c2 === o); //=> false
consloe.log(c2.x === o.x); //=> false
-------------------------------------------------------
const v = 1;
// 깊은 복사
const c1 = v;
console.log(c1 === v): //=> true
const o = { x: 1 };
// 얕은 복사
const c2 = o;
console.log(c2 === o): //=> true
" 값에 의한 전달 "과 "참조에 의한 전달"
식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서 동일
자바스크립트에는 "값에 의한 전달"만이 존재
var person1 = {
nameL: 'Lee'
};
var person2 = {
nameL: 'Lee'
};
// 객체의 내용이 같지만 다른 메모리에 저장된 별개의 객체
console.log(person1 === person2); // => false
// 프로퍼티 값을 참조하는 표현식, 동일 원시 값으로 평가
console.log(person1.name === person2.name); // => true