veggie의 기술기록
[JavaScript] 평가전략 - 'Call By Value' vs 'Call By Reference' 본문
위키피디아에 따르면 자바스크립트의 평가전략이란
프로그래밍 언어에서 함수 호출의 아규먼트(argument)의 순서를 언제 결정하고 함수에 어떤 종류의 값을 통과시킬지 결정하는 것이다.
Call By Value
- arguments로 값이 넘어온다.
- 값이 넘어올 때 복사된 값이 넘어온다.
- caller(호출하는 녀석)가 인자를 복사해서 넘겨줬으므로 callee(호출당한 녀석)에서 해당 인자를 지지고 볶아도 caller는 영향을 받지 않는다.
ex) var a = 1;
function b(c){
c = 2;
}
b(a);
console.log(a);
위 코드의 실행결과는 2가 아닌 1이다. 왜냐하면 arguments로 a의 값인 1이 복사되어 함수 b의 매개변수로 넘어간다.
값을 복사해서 넘겨줬을 뿐이므로 callee에서 아무리 변형을 줘도 a의 값은 변하지 않는다. 복사된 값은 함수 내에서 지역적으로 사용되는 local value라는 특징을 가지고 있다.
Call By Reference
- arguments로 reference(값에 대한 참조 주소, 메모리 주소를 담고있는 변수)를 넘겨준다.
- reference를 넘기다 보니 해당 reference가 가리키는 값을 복사하지는 않는다.
- caller(호출하는 녀석)가 인자를 복사해서 넘기지 않았으므로 callee(호출당한 녀석)에서 해당 인자를 지지고 볶으면 caller는 영향을 받는다.
ex) var a = {age : 20};
function b(c){
c.age++;
}
b(a);
console.log(a.age);
위 코드의 결과는 20이 아닌 21이다. 객체의 값이 아닌 reference를 넘겼으므로 caller가 영향을 받는다.
객체나 배열을 넘기면, 값이 복사되어서 넘어가는게 아니라 객체를 가리키는 리모콘이 늘어나는거라고 생각하면 된다.
하지만 위의 예시만으로 Call By Refefence는 값을 변경할 수 있구나 라고 단정지으면 안된다.
ex) var a = {name : 'veggie'};
function b(c){
c = {name : 'vegetable'};
}
b(a);
console.log(a.name);
위 코드의 결과는 'vegetable'이 아닌 'veggie'이다. 왜?? 똑같이 객체의 reference를 넘겼기 때문에 name의 값이 변해야하는거 아닌가?라고 생각할 수도 있다. 하지만 처음부터 차근차근 생각을 해보면 이해가 간다.
함수 b가 호출될 때 매개변수로 객체 a의 reference가 넘어가 c에 담겨 여기까진 a와 c가 같은 객체를 바라보고 있다.
마지막으로 함수 내부가 실행되는데, 이때 새로운 객체가 인수 c에 할당된다. 결과적으로 a와 c는 다른 객체를 바라보게 되기 때문에 a의 name은 그대로 'veggie'로 남게 된다.
변수의 레퍼런스와 인스턴스의 레퍼런스를 구분해야한다.
Call By Reference의 첫번째 예제에선 변수 자체의 레퍼런스를 넘겼기 때문에 변경이 가능한걸로 보인다.
'IT_JavaScript' 카테고리의 다른 글
[JavaScript] document.forms 객체 (0) | 2021.11.16 |
---|---|
[JavaScript] 'Parameter' vs 'Arguments' (0) | 2021.10.04 |
[JavaScript] 호이스팅(Hoisting)이란? (0) | 2021.10.03 |
[JavaScript] 배열과 객체 (0) | 2021.09.26 |
[JavaScript] form태그의 target 속성 (0) | 2021.09.25 |