Call by value와 Call by reference,call by sharing

장운서·2022년 1월 17일
0

이론

목록 보기
3/3

call by ...

call by ...라는 것은 평가 전략(Evaluation Strategy) 중 하나이며 위키피디아에서는 아래와 같이 서술하고 있다.

프로그래밍 언어에서 함수 호출의 아규먼트(argument)의 순서를 언제 결정하고 함수에 어떤 종류의 값을 통과시킬지 결정하는 것

즉 함수에 인자로 뭘 던지느냐에 따라서 함수가 어떻게 실행될지에 대한 방법을 결정하는 것이라고 보면 된다.
여러가지 호출 방법들이 있지만 오늘은 대표적인 call by value 와 call by reference 에 대해 살펴보도록 하자.

parameter 와 arguments 의 차이

함수의 호출 방법들을 알아보기 전에 parameter 와 arguments의 개념들을 간단하게 정리하고 넘어가도록 하자

매개변수(parameter)는 전달된 값을 받아들이는 변수를 의미한다, 즉 함수 선언부에서 들어가는 값은 매개변수, 형식적인 매개변수라고 칭한다.
인자(arguments)는 함수 호출부에서 실제로 반영 되는 값, 실인자라고 칭한다.

let a = 1;
let b = 2
function sum(a,b){ // a,b 는 매개변수(parameter)
	return a,b
}

sum(a,b); // 10,20은 인자(agrument)

Call by value

call by value(값으로 호출)은 말 그대로 복사된 값을 인자로 넘겨서 매개변수로 전달한다는 의미다. 즉 함수 호출부에서 어떠한 값을 넘기던(caller) 그 값 자체는 영향을 받지 않는다 해당 값을 복사 해서 사용하기 때문이다.

let a = 1;
let func = function(b){
  b = b+1;
  
  return b;
}
console.log(func(a)); // caller , 2
console.log(a); // 1

call by refernce

call by refernce(주소값의 복사)는 실제 데이터가 존재하는 주소를 가리키는 주소값을 인자로 넘겨서 매개변수로 전달한다는 의미이다.
객체는 call by reference 방식으로 전달된다.

var a = {};
var func = function(b) { // callee
  b.a = 1;
}
func(a); // caller
console.log(a.a); // 1

여기서 흔히들 오해할수있는 부분이 생긴다.
자바스크립트는 참조 타입을 arguments로 넘겨주면 call by reference의 형태로 작동하는 것 처럼 보일수 있기 때문이다.
caller가 객체 a를 parameter로 넘겼을 때 실제 arguments로 넘어오는 값은 객체 a에 대한 referene이지 복사된 객체 a가 아니다.
따라서 caller 내부에서 값을 가공하면 영향을 받기 때문에 조심해서 사용해야 한다 라고 생각할수 있다.

call by sharing

call by reference에서 끝날줄 알았는데 call by sharing 이란 개념이 나와 버렷다.


var a = {};
var func = function(b) { // callee
  b = 1;
}
func(a); // caller
console.log(a); // {}

js 에서는 객체 자체의 값을 가공하는 행위를 허용하지 않는다.
겉으로는 주소값을 참조하는 것 같지만 실제로는 주소값의 복사본을 만들어서 넘기기 때문이다.

아래 그림을 참고하면서 자세하게 확인해보자

먼저 foo(obj1);에서 obj1이 함수 foo()의 인자로 넘어가서 obj2라는 매개변수로 전달될 때, obj1이 가리키고 있는 주소값과 동일한 주소값을 가진 obj2가 복사되서 전달된다.

그 다음 함수 내부의 obj2 = 10; 에서 obj2의 주소값이 10 이 저장된 위치의 주소값으로 변경된다.

결론적으로 두 객체는 다른 객체이다.


var a = {};
var func = function(b) {
  b = (b.a=1);
  //console.log((b.a=1));
   b.b = 2;
}
func(a);
console.log(a); // ??

위 값은 어떻게 찍힐까













답은 {a:1}이다
(b.a=1)에서 ba를 쳐다보기 때문이다.
(그리고 a.a를 호출하면 해당 메모리 값을 참조하기 때문에 a.a, a.b, a.c등등에 접근이 가능하다)
그 후에 b라는 값에 b.a의 결과를 할당해버려 b는 더이상 a가 아닌 1로 향하기 때문에 b.b=2라고 a값은 그 값이 어디있는지 알수가 없게된다

var a = {};
var func = function(b) {
  console.log(b)
  b = (b.a=1);
  b = (b.b=2); // 할당안됨
  console.log(a.a) // 1
  console.log(b)// undefined
  console.log(b.b);// undefined
  console.log(b.a); // undefined
  b.b = 2;
  console.log(b) // 1
}
func(a);
console.log(a); // {a:1}
profile
방향성을 찾고싶은 프론트엔드개발자

0개의 댓글