GYUMIN DEV LOG

  • javascript는 포인터라는 개념 자체가 없음, 또한 참조하는 방법도 조금 다름.
  • 어떠한 변수가 다른 변수를 참조 하는 것은 불가.
  • javascript에서 레퍼런스란 값을 가리킴. 서로 다른 10개의 레퍼런스가 있다면, 각각 항상 공유된 단일 값을 개별적으로 참조한다.
  • 특히 문법적으로 레퍼런스의 할당 및 전달을 제어할 수 있는 암시(책에서는 Syntactic Hint라고 표현)가 전혀 없음.
  • 그래서 값의 타입만으로 값 복사 / 레퍼런스 복사 둘 중 한쪽이 결정됨.

 

스칼라 원시 값은 언제나 깊은 복사(값) 방식으로 할당/전달 됨.

  • null
  • undefined
  • string
  • number
  • boolean
  • symbol

 

객체 및 배열, 함수는 언제나 얕은 복사(레퍼런스) 방식으로 할당/전달 됨.

 

// b는 언제나 a의 값을 복사함.
const a = 2
let b = a
b++
a // 2
b // 3

// d는 [1, 2, 3] 값의 레퍼런스임.
let c = [1, 2, 3]
let d = c
d.push(4)
c // [1, 2, 3, 4]
d // [1, 2, 3, 4]

// c와 d는 공유된 값 [1, 2, 3]에 대한 개별 레퍼런스임.

즉, 레퍼런스는 변수가 아닌 값 자체를 가리키는 것.

 

let a = [1, 2, 3]
let b = a

a // [1, 2, 3]
b // [1, 2, 3]

b = [4, 5, 6]

a // [1, 2, 3]
b // [4, 5, 6]

let b = a 라고 해서 b가 a를 가리키는 포인터가 되는 것이 아니라 값 [1, 2, 3]의 레퍼런스가 됨.

그러므로 b = [4, 5, 6]으로 할당해도 영향을 받지 않음.

 

function test(x) {
  x.push(4)
  x // [1, 2, 3, 4]
  
  x = [4, 5, 6]
  x.push(7)
  x // [4, 5, 6, 7]
}

let a = [1, 2, 3]

foo(a)

a // [1, 2, 3, 4]

포인터의 개념이 없기 때문에 위와 같이 함수 인자로 a가 주어지더라도 x = [4, 5, 6]으로 새 값을 할당해도 영향이 없음.

 

function test(x) {
  x.a = 42
}

let obj = {
 a: 2
}

test(obj)
obj.a // 42

obj는 스칼라 값을 가지고 있는 a를 감싼 객체(책에서는 Wrapper)로 test 함수에 obj 레퍼런스 사본이 전달되어 a의 값을 바꿈.

 

이와 같이 javascript는 값의 타입에 따라서 깊은 복사 / 얕은 복사가 이루어짐!!!

 

 

참조 : You Don't Know JS

'Web > javascript' 카테고리의 다른 글

1. 타입 (null 체크, undefined 체크 etc..)  (0) 2019.06.11