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가 나온다.

 

 

 

위의 링크에 더 자세한 설명이 나온다.

+ Recent posts