⇒ 문자열, 숫자, 불리언, null, undefined, 심벌, 객체 타입
원시 타입 | 객체 타입 |
---|---|
변경 불가능한 값 | 변경 가능한 값 |
원시 값 변수에 할당 시, 실제 값 저장됨 | 객체를 변수에 할당 시, 참조 값 저장됨 |
원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달 ⇒ 값에 의한 전달 | 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달 ⇒ 참조에 의한 전달 |
원시 타입의 값, 즉 원시 값은 변경 불가능한 값 ⇒ 읽기 전용(read only) 값으로서 변경 불가능
❗️원시 값 자체를 변경할 수 없다는 것! 변수 값을 변경할 수 없다는 것이 아님!
// const 키워드를 사용해 선언한 변수는 재할당 금지
const o = {};
// const 키워드를 사용해 선언한 변수에 할당한 원시 값(상수)는 변경 불가능
// 하지만 const 키워드 사용해 선언한 변수에 할당한 객체는 변경 가능
o.a = 1;
console.log(o); // {a: 1}
```
문자열: 0개 이상의 문자로 이뤄진 집합, 1개의 문자는 2바이트
의 메모리 공간에 저장됨
유사 배열 객체
마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체var str = 'string'; // 문자열은 유사 배열이므로 배열과 유사하게 인덱스를 사용해 각 문자에 접근 가능 console.log(str[0]); // s // 원시 값인 문자열에 객체처럼 동작 console.log(str.length); // 6 consoel.log(str.toUpperCase()); // STRING
var str = 'string';
str[0] = 'S';
console.log(str); // string
var score = 80;
var copy = score;
console.log(score); // 80
console.log(copy); // 80
score = 100;
console.log(score); // 100
console.log(copy); // 80
변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달됨 ⇒ 값에 의한 전달
score 변수와 copy 변수의 값 80은 다른 메모리 공간에 저장된 별개의 값임
따라서, score 변수 값을 변경해도 copy 변수의 값에는 어떠한 영향도 주지 않음
var score = 80;
// copy 변수에는 score 변수의 값 80이 복사되어 할당됨
var copy = score;
console.log(score, copy); // 80 80
console.log(score === copy); // true
// score 변수와 copy 변수의 값은 다른 메모리 공간에 저장된 별개의 값
// 따라서 score 변수의 값을 변경해도 copy 변수의 값에는 어떠한 영향 주지 않음
score = 100;
console.log(score, copy); // 100 80
console.log(score === copy); // false
❗️ 실제 JS 엔진 내부 동작과 정확히 일치하지 않을 수 있음(두 가지 평가 방식 존재)
값에 의해 전달된 값은 다른 메모리 공간에 저장된 별개의 값
변수에 원시값을 갖는 변수를 할당하는 시점에는 두 변수가 같은 원시 값을 참조하다가 어느 한쪽의 변수에 재할당이 이뤄졌을 때 비로소 새로운 메모리 공간에 재할당된 값을 저장하는 경우
“값에 의한 전달”
이라는 용어는 자바스크립트를 위한 용어가 아님! ⇒ 변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달되기 때문에 변수와 같은 식별자는 값이 아니라 메모리 주소를 기억하고 있음
⭐️ 어쨋든, 중요한 것은 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없음
[객체 특징]
[객체의 관리 방식]
프로퍼티 키를 인덱스로 사용하는 해시 테이블과 유사
객체(참조) 타입의 값, 즉 객체는 변경 가능한 값
var person = {
name: 'Lee'
};
객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값에 접근 가능
참조 값: 생성된 객체가 저장된 메모리 공간의 주소
객체를 할당한 변수는 재할당 없이 객체를 직접 변경 가능 ⇒ 프로퍼티 동적으로 추가하거나 값 갱신 및 삭제 가능
var person = {
name: 'Lee'
};
// 프로퍼티 값 갱신
person.name = 'Kim';
// 프로퍼티 동적 생성
person.address = 'Seoul';
console.log(person); {name: 'Kim', address: 'Seoul'}
객체는 원시 값과 다르게 여러 개의 식별자가 하나의 객체 공유 가능 → 부작용 존재
❗️얕은 복사와 깊은 복사
얕은 복사: 한 단계까지만 복사하는 것, 객체에 중첩되어 있는 객체의 경우 참조 값을 복사 ⇒ 객체를 할당한 변수를 다른 변수에 할당하는 것
const o = { x: { y: 1}};
// 얕은 복사
const c1 = {...o};
console.log(c1 === o); // false
console.log(c1.x === o.x); // true
깊은 복사: 객체에 중첩되어 있는 객체까지 모두 복사하는 것, 객체에 중첩되어 있는 객체까지 모두 복사해서 원시 값처럼 완전한 복사 만듦 ⇒ 원시 값을 할당한 변수를 다른 변수에 할당하는 것
원본과 복사본은 참조 값이 다른 별개의 객체
const v = 1;
// 깊은 복사
const c1 = v;
console.log(c1 === v); // true
const o = {x:1};
// 얕은 복사
const c2 = o;
console.log(c2 === o); // true
여러 개의 식별자가 하나의 객체 공유 가능
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'}
===
비교 일치 연산자는 변수에 저장되어 있는 값을 타입 변환하지 않고 비교 → 객체를 할당한 변수를 비교하면 참조 값 비교하고, 원시 값을 할당한 변수 비교하면 원시 값 비교var person1 = {
name: "Lee",
};
var person2 = {
name: "Lee",
};
console.log(person1 === person2); // false
console.log(person1.name === person2.name); // true