데이터 타입에는 원시 데이터 타입과 객체 데이터 타입이 있다. 원시 데이터 타입은 기본 데이터 타입, 객체 데이터 타입은 참조 데이터 타입으로도 불린다.
숫자, 문자열, boolen, null, undefined 는 primitive type(원시 타입) 그 외는 객체(참조) 데이터 타입이다.
str.length를 사용할 때 자바스크립트는 순간적으로 str = new String()으로 객체화 한다. 그리고 곧 제거한다. 하지만 어떤 문자열 str에 str.prop = "hi"라고 할당하고 console.log를 해보면 undefined를 출력한다. 그 이유는 prop이라는 속성이 저장된 객체는 곧 바로 제거되고 원시 데이터 타입이 되기 때문이다.
임시로 자바스크립트가 원시 데이터 타입을 객체화 한 것을 래퍼 객체(wrapper object)라고 한다.
let a = 1;
let b = a;
b = 2;
console.log(a) // 1
a라는 변수에 1이라는 값을 담고 있다. (값을 메모리에 저장되었다/ a가 1을 가리키고 있다.) 변수 b는 변수 a다. b의 값에 1을 준 것이 아니라 1을 담고 있는 a를 준 것이다. 그리고 b에 2를 담게 하고 a를 출력하면 1이 나온다.
순서는 이러하다. a는 1을 가리키고 그것을 복사한 b도 1을 가리킨다. a와 b는 각기 다른 1을 가리키고 있는데 이 때 b를 2로 수정하면 b는 2가 되고 a는 여전히 1을 가리킨다.
변수의 값이 원시 데이터 타입일 때 이러한 복제가 일어난다.
let a = {
"key" : 1
}
let b = a;
b.key = 2;
console.log(a.key) // 2
아까 예제와 다른 점은 a라는 변수가 key: 1이라는 프로퍼티를 가지고 있는 객체가 되었다는 것이다. 똑같이 b에 a를 복제하고 b.key 로 value의 값을 바꾸고 a.key의 값을 출력하면 바꾼 2가 출력된다. b에 담겨있는 객체의 프로퍼티 값을 변경하면 a 도 같이 바뀐다.
순서는 원시 데이터를 복제하는 방식과 비슷하다. a를 만들고 객체 {"key" : 1}
를 할당하면 a는 그 객체를 가리킨다. 그리고 let b = a
라고 했을 때 원시 데이터의 경우 1이 하나 더 만들어지고 b는 만들어진 1을 가리켰지만 객체의 경우 기존의 객체를 b도 참조하게 된다. 그래서 b의 key 값을 변경하면 a의 key값도 변경된다.
let a = {
"key" : 1
}
let b = a;
b = {
"key" : 2
}
b.key = 3;
console.log(a.key, b.key) // 1, 3
코드를 조금 바꿔서 b에 똑같은 프로퍼티를 가지고 있는 객체를 할당하고 b.key의 값을 바꿨다. 그리고 a.key와 b.key의 값을 출력하면 a는 원래의 1을 b는 바뀐 3을 출력한다.
객체를 새롭게 생성하여 변수 b에 할당한 것이다.
let a = 1;
function func(b){
b = 2;
}
func(a)
console.log(a) // 1
a가 1을 가리키는 상황에서 func()는 b를 파라메터로 받고 내부에서 b = 2라고 할당했다. 그리고 func(a)를 넣고 console.log(a)를 해보면 1이 출력된다. func()에 a를 인자로 넣으면서 b = a가 되었다. b는 함수 내부에서 2가 되었다. func()에 a 인자를 넣은 순간 복제가 되어 서로 다른 1를 바라보게 되었으므로 a의 값은 여전히 1이다.
let a = {
"key" : 1
}
function func(b){
b.key =3
}
func(a)
console.log(a.key) // 1
이번엔 a 에 객체를 할당하고 func()안에 b에 다른 값을 가지는 객체를 할당했다. 그리고 func()에 a 를 인자로 주고 a.key 를 출력하면 여전히 1이다. 함수 내부에서 b에 새로운 객체를 할당했기 때문에 a의 프로퍼티와는 연관이 없는 것이다.
만약 함수 내부에서 b.key =3
라고 정의하면 a.key의 값은 바뀐다.