티스토리 뷰

 

프로그래밍 언어마다 따르고 있는 평가 전략이 존재한다. JS의 경우에는 Call by Sharing을 따른다. 이 게시글을 작성하고자 하는 요지는 Call by Sharing에 대해서 설명하고자 하는 것이지만 이를 이해하기 위한 부가적인 설명을 먼저 작성한 뒤에 본 요지에 대한 내용을 작성하려고 한다.

 


JS의 데이터 타입

 

1. JS 데이터 타입의 종류로는 Primitive type와 Object로 나뉜다.

 

-Primitive type은 가장 작은 단위를 뜻한다. number, string, boolean, null, undefined, symbole, bigInt가 존재한다.

(보통 Primitive type은 변수에 담아서 사용한다.)

 

-그 외의 모든 것을 Object 라고 보면 된다. array, list, function, object 등이 존재한다.

 

2. JS를 통해 코드를 작성할 때 Primitive type을 a라는 변수에 할당을 한다면 해당 데이터가 메모리에 저장이 될 때 a는 그 값 자체를 가리키게 된다.

 

반면 Object의 경우 ref(Reference)라는 참조값이 생성이 되는데 b 라는 변수에 Object를 할당했을 때 b가 그 값 자체를 가리키는 것이 아닌 ref를 가리키게 되고 이 ref가 해당 데이터가 저장되어 있는 메모리를 가리키게 된다.

 

let a = 'Hello';

//이렇게 Primitive type인 Hello라는 string을 a 변수에 할당했다고 가정해보자.
//Hello는 메모리 어딘가에 저장이 되고 a는 Hello가 저장된 메모리를 직접 가리키게 된다.

let b = {name: 'pizza'};

//이렇게 object를 b 변수에 할당했다고 가정해보자.
//이 object는 메모리 어딘가에 저장이 되는데 b는 object를 직접 가리키고 있지 않게 된다.
//ref라는 것이 중간에 생성된다고 생각하면 된다. b는 ref를 가리키고 ref는 object가 저장된 메모리를 가리키게 된다.

 

위의 코드를 바탕으로 이번에는 a와 b의 변수를 다른 변수에 할당을 한다면 과연 메모리에는 데이터가 어떤 식으로 저장이 될까? 아래 코드를 통해 알아보자.

 

let a = 'Hello';

let b = {name: 'pizza'};

//위의 a와 b의 변수를 아래의 x와 y의 변수로 재할당을 해보자.

let x = a;

let y = b;

//x는 a의 값인 Hello를 새로운 메모리에 저장을 하여 그곳을 가리키게 된다.

//y는 b의 값인 obj의 ref를 복사한 새로운 ref를 만들게 된다. 하지만 새로운 메모리에 obj를 새로 저장하는 것이 아니라 기존 obj가 저장된 메모리를 복사된 ref가 가리키게 된다.

즉 Primitive type의 데이터를 새로운 변수로 재할당을 하면 새로운 메모리에 저장이 되어 그곳을 가리키게 되고, object의 경우에는 새로운 메모리에 저장을 하는 게 아니라 ref를 복사하여 기존의 값을 가리키게 된다.

 

 

*한 줄 요약

=> primitive는 값 자체가 복사가 된다. / obj는 ref가 복사가 된다.

 


Call by Value와 Call by Reference

 

*위에서 JS의 데이터 타입에 대해서 설명한 이유는 이 개념과 연결이 되기 때문이다. Primitive type과 object의 특성을 이해하면 자연스럽게 이 개념을 이해할 수 있게 된다. 미리 언급을 하자면 JS의 경우에는 'Call by Sharing' 이라는 평가 전략을 따르는데 이를 배우기 전에 먼저 Call by Value와 Call by Reference을 이해해야 한다.

 

1.  Call by Value와 Call by Reference는 ‘평가 전략(Evaluation Strategy)’ 이라고 부른다. 여러 프로그래밍 언어들은 각자 따르고 있는 평가 전략이 존재한다.

 

변수나 객체등이 함수의 인자(argument)로 들어와 매개변수(parameter)로 전달될 때 어떤 방식으로 전달될지를 결정하는 방식이다.

 

이게 중요한 이유는 코드를 작성할 때 어떤 값을 변수에 넣어서 그 변수를 함수의 매개변수에 전달하여 함수에서 사용하고자 할 때 함수 내부에서 해당 변수를 재할당을 한 경우 기존의 값이 바뀌게 될 수도 있기 때문이다.

 

한 가지의 함수만을 사용하는 로직이라면 상관없겠지만 해당 변수를 가지고 여러 곳에서 재사용을 하려고 하는 경우라면 문제가 될 수 있기 때문에 이를 이해하는 것은 매우 중요하다.

 

 

Call by Value

 

-일반적으로 원시형(primitive)은 Call by value 방식으로 넘긴다.

 

-장점: 기존의 값을 복사하여 새로운 메모리에 저장하기 때문에 함수 내에서 재할당을 한다고 해도 기존의 값이 보존이 된다.

 

-단점: 새로운 메모리에 저장을 하기 때문에 메모리 사용량이 늘어난다.

 

 

Call by Reference

 

-참조형(ref)은 Call by reference 방식으로 넘긴다.

 

-장점: 기존의 값을 복사하지 않고 직접 참조를 하기 때문에 빠르다.

 

-단점: ref를 전달받는 거라 기존 메모리에 있는 값을 가리키기 때문에 값을 변경하면 기존 값이 변경되는 위험이 있다.

 

 

*한 줄 요약

=> Call by vaule는 기존 값에 영향을 주지 않고 / Call by Reference는 기존 값에 영향을 준다.

 


Call by Sharing

 

JS는 Call by Sharing을 따른다. Call by Value와 Call by Reference와 비슷하지만 실제로 JS를 통해 코드를 작성해 보면 다른 점이 있기 때문에 Call by Value와 Call by Reference의 평가 전략을 선택했다고 보기 어렵다.

(마치 이탈리아인이 바라보는 한국식 피자 같은 느낌..?)

 

아래의 코드를 통해 이를 설명하고자 한다.

function test(value, after1, after2){
  value += value;
  after1.name = 'hello';
  after2 = {name : 'hello'};
}

let num = 1;
let obj1 = {name : 'hi'};
let obj2 = {name : 'hi'};

test(num,obj1,obj2);

//num, obj1, obj2를 변수에 할당한 뒤 test 함수에 인자로 전달한 뒤
//test 함수에서 이들을 매개변수로 받아서 재할당을 하는 코드이다.
//아래에 기존의 값들은 num, obj1, obj2의 값이 변하는지를 살펴보자.

console.log(num); // 1 => 변하지 않는다.
console.log(obj1); // {name: 'hello'} => 변한다.
console.log(obj2); // {name: 'hi'} => 변하지 않는다.

 

-num의 경우 primitive type으로서 Call by value의 형태로 함수의 매개변수로 전달이 된다. 그렇기 때문에 함수 내부에서 value라는 변수로 재할당을 했어도 기존의 num의 값은 변하지 않게 된다.

 

-반면 obj1의 경우 object로서 Call by reference의 형태로 함수의 매개변수로 전달이 된다. 그렇기 때문에 함수 내부에서 after1이라는 변수로 재할당을 했을 때 기존의 obj1의 값이 변하게 된다.

 

-obj2의 경우 때문에 JS를 Call by Value와 Call by Reference로 칭할 수가 없게 된다. object type으로 전달된 거라 obj1의 경우처럼 재할당을 하면 기존의 값이 변해야 하는데 변하지 않는다.

 

*JS는 obj1의 케이스처럼 객체의 property를 재할당 할 때는 Call by Rererence의 형태처럼 기존의 값이 변하지만 obj2의 케이스처럼 아예 객체 자체를 재할당 하는 경우에는 기존의 값이 변하지 않는다. 이러한 특징 때문에 Call by Sharing이라고 부른다.

(Call by Reference는 재할당을 할 때 ref를 '전달' 하는 방식으로 운영되는데 JS는 ref를 '복사' 하기 때문에 이런 현상이 생기는 것이다.)

 

*obj1과 obj2는 매개변수로 전달이 되는 순간 ref가 복사되고 after1 after2 변수에 재할당이 되면 일단 obj1,2가 가리키는 객체를 똑같이 가리키게 되지만, obj2 처럼 새로운 객체를 할당시켜 버리면 메모리에 새롭게 객체가 들어가게 되고 복사되었던 ref가 새로 생긴 객체를 가리키게 된다.

 

 

*한 줄 요약

=> JS는 Call by Sharing 평가 전략을 따른다. 객체의 프로퍼티 값(after1)의 변경은 기존값에 영향을 주지만, 객체 자체(after2)의 변경은 기존값에 영향을 주지 않는다.

'기술 노트' 카테고리의 다른 글

모듈을 Import 할 때 { }(중괄호)를 쓰는 경우와 아닌 경우(Node.js)  (0) 2023.03.15
DOM이란?  (0) 2023.03.11
IP란?  (0) 2023.03.09
CDN이란?  (1) 2023.03.07
캐시(Cache)란?  (0) 2023.03.07
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함