원시값을 변수에 할당하면 변수에는 실제 값이 저장된다. 이에 비해 객체를 변수에 할당하면 변수에는 참조 값이 저장된다.
원시값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다. 이를 값에 의한 전달이라한다. 이에 비해 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다. 이를 참조에 의한 전달이라한다.
var str = 'Hello';
str = 'world';
var str = 'string';
console.log(str[0]); // s
str[0] = 'S'; // 오류없음
var score = 80;
var copy = score;
console.log(score); //80
console.log(copy); // 80
score = 100;
console.log(score); // 100
console.log(copy); //?
값에 의한 전달이라고 표현은 했지만 더 정확하게 말하자면 메모리 주소가 전달이 된것이다. 이는 변수와 같은 식별자는 값이 아니라 메모리 주소를 기억하고 있기 때문이다.
전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있다!
자바스크립트 객체의 관리 방식!!
자바스크립트 객체는 프로퍼티 키를 인덱스로 사용하는 해시 테이블(해시테이블은 연관 배열)이라고 생각할 수 있다. 대부분의 자바스크립트 엔진은 해시 테이블과 유사하지만 높은 성능을 위해 일반적인 해시 테이블보다 나은 방법으로 객체를 구현한다.
var person = {
name: 'Lee'
}
// 할당이 이뤄지는 시점에 객체 리터럴이 해석되고, 그 결과 객체가 생성된다.
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 o = { x: { y: 1 } };
// 얕은복사
const c1 = { ...o}; // 스프레드 문법
console.log(c1 === o); // false
console.log(c1.x === o.x); // true
//lodash의 cloneDeep을 사용한 깊은 복사
const _ = require('lodash');
//깊은 복사
const c2 = _.cloneDeep(o);
console.log(c2 === o); //false
console.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 person = {
name: 'Lee'
};
// 참조 값을 복사(얕은 복사)
var copy = person;
참조에 의한 전달은 서로 다른 식별자가 얕은 복사를 통해 하나의 객체를 공유한다는 것이다.