자바스크립트 평가 전략

call by value와 call by reference 그리고 더 나아가 call by sharing에 대한 개념을 알아보자

7 Data Types

7가지 데이터 유형은 아래와 같다.

  • primitive data type - number, string, boolean, undefined, null

  • Objects - Array, Object

call by value

primitive data type으로 전달되고, Objects참조로 전달된다. 여기서 **값으로 전달된다(Call by value)**는 의미는 사본을 만드는 것과 동일하다고 생각하며 되며, 좀 더 정확하게는 다른 메모리 위치에 저장된다. 아래 예제를 보자.

let name = 'jacob';
let newName = name;

name = 'master jung';

console.log(newName); // jacob
console.log(name); // master jung

변수 name이 생기고 'jacob'이 할당된다. 그리고 변수 newName이 생기고 name의 값이 할당되며, 'name'과 'newName'은 별도의 메모리를 참조하고 있다.

그런데 여기서 name의 값에 'master jung'을 할당했더라도 여전히 다른 곳을 참조하고 있기 때문에 newName에는 영향을 미치지 않게 되는 것이다.

기본 데이터 타입을 함수에 전달할 때도 동일하다. 변수가 함수에 매개 변수로 전달 될 때, 변수가 변경되면 원래 변수는 영향을 받지 않는다. 이건 모든 기본 데이터 유형**(primitive data type)**을 가진 모든 값에 적용된다.

let name = 'jacob';
function changeName(name) {
	name = 'master jung';
    return name;
}

console.log(changeName(name));
console.log(name);

위에서 식에서 과연 콘솔에는 어떤 값이 나올까?

master jung, jacob 순서대로 콘솔에 출력된다.

왜 이렇게 출력될까?

정답은 위에서 언급한 내용과 같다. changeName이라는 함수의 매개 변수에 전달할 때 기본 데이터 유형의 값이 으로 전달 된다. 즉 참조하고 있는 메모리 주소가 아닌 으로 전달되기 때문에 함수에서 변수에 대한 모든 변경 사항이 함수 외부에서 발생하는 변수와 완전히 분리되고, 값을 변경해도 원래 값의 실제 참조는 업데이트 되지 않는다.

Call by reference

**기본 데이터가 아닌 유형(non-primitive data type)**의 변수를 함수의 매개 변수로 전달되면, 원래 변수의 참조가 업데이트 된다. 즉 값이 아닌 **참조(모두 동일한 위치)**로 전달되며, 이것을 Call by reference라고 한다.

let nameObj = {
	name: 'jacob'
}
function changeName(nameObj) {
	return nameObj.name = 'master jung';
}

console.log(changeName(nameObj));
console.log(nameObj);

이번에는 과연 어떻게 값이 출력되었을까?

call by reference가 적용되는 경우이기 때문에 콘솔에는 master jung, master jung가 출력된다. 왜냐하면 객체로 전달하면 값이 아닌 참조로 전달되기 때문이다.

더 나아가기

아래의 결과값을 예측해 보자.

let nameObj = {
	name: 'jacob'
}
function changeName(nameObj) {
	nameObj = {
		name: 'master jung',
    }
	return nameObj;
}

console.log(changeName(nameObj));
console.log(nameObj);

정답은 master jung, jacob 순으로 콘솔에 찍힌다. 이유는 아래와 같다.

call by sharing

call by sharing 이라는 개념이다. 실제로 존재하는 평가 전략임에도 불구하고 일반적으로 사용되는 용어는 아니다(자바에서는 call by value)로 부르기도 한다. call by sharing은 값이 primitive 유형이 아닌 Objects 유형을 기반으로 한다.

이 개념은 복잡하게 생각하지 말자. 우리가 인수에 전달하는 객체는 객체 자체가 아닌 객체 또는 배열에 대한 참조가 함수에 전달되는 것이다. 그리고 그 참조를 사용하여 배열의 객체 또는 요소의 속성을 수정할 수 있다. 그러나, 함수가 참조를 새 객체 또는 배열에 대한 참조로 덤어 쓰면 새로운 메모리에 참조되며, 외부 객체에 영향을 주지 않는다.

참고 자료

https://docstore.mik.ua/orelly/webprog/jscript/ch11_02.htm

Last updated