모던 JS 딥다이브 공부 정리용 글입니다.
- 원시 타입의 값은 변경 불가능한 값이다 <-> 객체 타입의 값은 변경 가능한 값이다.
- 원시값을 변수에 할당하면 변수(확보된 메모리 공간)에는 실제 값이 저장
- 객체를 변수에 할당하면 변수에는 참조값이 저장
- 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달(pass by value)
- 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달(pass by reference)
- 원시 값을 할당한 변수에 원시 값을 재할당하면
이전 원시 값을 변경하는 것이 아닌 새로운 메모리 공간을 확보하고
재할당한 원시 값을 저장한 후 새롭게 재할당한 원시 값을 가리킨다.
-> 결국 변수가 참조하던 메모리 공간의 주소가 바뀌는 것이다.
- 결론 : 불변성을 갖는 원시 값을 할당한 변수는 재할당 외에는 변수 값을 변경할 방법이 없다.
- JS는 개발자의 편의를 위해 원시 타입인 문자열을 제공한다.
var str = 'Hello';
str = 'world';
- 문자열은 유사 배열 객체!
- 유사 배열 객체란 마치 배열처럼 인덱스로 프로퍼티 값에 접근 가능하고 length 프로퍼티를 갖는 객체이다. 인덱스와 length 프로퍼티가 있기에 for문으로 순회도 가능하다.
var str = 'string';
str[0] = 'S';
console.log(str) // string
var score = 80;
var copy = score; // 레퍼런스가 아닌 값이 할당된 것.
score = 100;
console.log(score, copy) // 100, 80
score의 80과 copy의 80은 서로 다른 메모리에 저장된 별개의 값이다.
JS에는 사실 값에 의한 전달이란 용어가 없다. 결국 레퍼런스가 할당된 것이기 때문. 정확히 알고 싶으면 (144p~ 146p) 보자.
//gㅏㄹ당되는 시점에 객체 리터럴이 해석되며 객체가 생성됨
var person = {
name: 'Lee'
}
console.log(person.name)
// person변수에 저장된 참조 값으로 실제 객체에 접근.
👎 단점!!
- 여러 개의 식별자가 하나의 객체를 공유해버리게 됨!
😽 Shallow & Deep copy
- 얕은 복사는 한 단계까지만 복사
const o = {x:{y:1}}; //얕은 복사 const c1 = {...o} console.log(c1 === o) // false //전개연산자로 레퍼런스가 아닌 새로운 객체의 주소가 할당되었기 때문. console.log(c1.x === o.x) // true
// npm install lodash(deep copy위한 모듈)
const _ = require('lodash');const c2 = _.cloneDeep(o);
console.log(c2 === o) //false
console.log(c2.x === o.x) //false
상위, 하위 객체 모두 복사해버림.//둘 다 새로운 객체 레퍼런스가 부여됐단 말임.
객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다. 이를 참조에 의한 전달이라고 한다.
이 때 원본 변수와 복사 변수와 바인딩된 메모리 주소는 다르지만 메모리에 저장된 레퍼런스 주소는 동일하다.
그래서 두 개의 식별자가 하나의 객체를 공유하게 된다.
- 값에 의한 전달과 참조에 의한 전달은 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서 동일하다.
- 결국 JS에는 참조에 의한 전달은 존재하지 않고 값에 의한 전달만이 존재한다고 볼 수 있다.
var person1 = {
name: "Lee"
};
var person2 = {
name: "Lee"
}
console.log(person1 === person2) // false
console.log(person1.name === person2.name)// true