https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
Explaining Value vs. Reference in Javascript
A simple look at computer memory explains what’s happening
codeburst.io
javascript에서 Number, boolean, strings, null, undefined는 primitive 타입이며 값(value)에 의해 전달된다.
반면에 objects, arrays, functions은 객체로 볼 수 있고 참조(reference)에 의해 전달된다.
여기서 다른 언어와는 다르게 자바스크립트의 String은 char 타입의 배열이 아니다. 심지어 자바스크립트에는 char타입이 존재하지 않는다. String은 불변의 데이터 타입이다.
stirng의 변경은 데이터가 수정되는게 아니라 새로운 string을 만드는 것이다.
------
만약 primitive 타입이 변수에 할당된다면 그 변수가 primitive 타입 데이터를 갖고 있는거다.
이게 뭔 소리나면
var x = 10;
var y = x;
console.log(x, y);
x는 10을 갖고있고 y는 그 10을 복사해서 할당 받은거다. 즉 x의 값을 바꾼다고 해도 y는 바뀌지 않는다. 값을 전달했기 때문이다.
반면에 객체는 우리 컴퓨터 메모리에 공간을 만든다. 그리고 객체는 그 공간의 주소값을 받는다.
var arr = [];
arr.push(1);
예를들어 배열 arr을 만들면 메모리에 arr의 주소를 가진 메모리 공간이 생성된다.
push를 통해 값 1을 넣으면 arr에 1을 넣는게 아니라 arr이가 갖고 있는 주소를 참조하여 메모리에 가서 1을 넣는다.
이게 primitive 타입 데이터 복사와 다르게 작동하는데
var ref = [1];
var refcopy = ref;
ref.push(2);
console.log(ref, refcopy); // [1,2] , [1,2]
배열 1을 갖고 있는 ref를 refcopy에 복사하였다. 그리고 ref에 2를 넣고 둘다 출력해보았다.
그럼 ref가 [1,2]로 찍히고 refcopy는 [1]만 나와야 하는데 둘 다 [1,2] 가 나왔다.
refcopy는 ref의 값을 할당받은게 아니라 ref가 갖고있는 메모리 주소를 할당받았기 때문이다.
그럼 만약
var obj = { a: 'a' };
obj = { b: 'b' };
obj는 json형태의 a의 주소를 할당 받았다.
그리고 다시 b의 주소를 할당 받았다. 추가한게 아니라 다시 할당받았다.
그럼 메모리에 있던 a 값은 어떻게 되는가? 이제 더이상 그 주소를 가르키는 변수가 없는데 ?
이 경우에 자바스크립트 엔진은 이 a 값을 가비지컬렉션 대상으로 지정하여 메모리에서 지운다.
그렇기 때문에 프로그래머는 다시 그 값을 지정할 수 없다.
여기 또 다른 이슈가 있는데 == 연산자의 경우에
var arr1 = ['a'];
var arr2 = arr1;
console.log( arr1 === arr2 ); // true
var arr3 = ['a'];
var arr4 = ['a'];
console.log( arr3 === arr4 ); // false
===는 == 보다 더 엄격한 검사라고 대충 넘어가고 예제를 보면
arr1과 arr2는 같은 값을 가져 true가 나왔다. 왜 ? 같은 주소를 참조하고 있으니까
arr3과 arr4는 같은 데이터를 할당하는 듯 보이지만 둘은 서로 다른 메모리 주소를 갖고있다.
그래서 false가 나왔다.
다시 말해서 arr3 === arr4는 'a' === 'a' 을 하는게 아니라 arr3메모리주소 === arr4메모리주소 이걸 비교하는거다.
그래서false가 나온다.
위의 링크에 더 자세한 설명이 나온다.