참조타입
참조 타입
복잡한 상황에서 메서드를 호출하면 this
값을 잃어버리는 경우가 생긴다.
1 | let user { |
에러는 메서드를 호출할 때 this
에 undefined
가 할당되었기 때문에 발생했다.
왜 이런 현상이 일어날까?
(user.hi)()
는 정상 작동한다. 이는 (expression)()
형태에서는 참조 값이 아닌 함수 값 자체가 전달되기 때문이다.
참조 타입 자세히 알아보기
obj.method()
엔 연사이 두개 있다.
.
은 객체 프로퍼티obj.method
에 접근한다.- 괄호
()
는 점근한 프로퍼티를 실행한다.
첫번째 연산에서 얻은 this
가 어떻게 두번째 연산으로 전달 될까?
1 | let user = { |
자바스크립트에서 user.hi()
를 의도한대로 동작 시키기 위해서 .
은 함수를 반환 시키는 것이 아니라 참조 타입을 반환하게 된다.
참조 타입에 속하는 값은 (base, name, strict)
이 조합된 형태이다.
- base: 객체
- name: 프로퍼티 이름
- strict: 엄격 모드에서 true
user.hi()
로 프로퍼티에 접근하면 함수가 아닌, 참조형(참조 타입) 값을 반환한다. 엄격 모드에선 아래와 같이 반환된다.
1 | // 참조형 값 |
참조형 값에 ()
를 붙여 호출하면 객체, 객체의 메서드와 연관된 모든 정보를 얻는다. 이 정보를 기반으로 this(=user)
가 결정된다.
참조 타입은 .
연산에서 알아낸 정보를 괄호 ()
로 전달해 주는 중개인 역할을 한다.
()
없이 user.hi
를 호출하면 점연산이 아닌 연산이 된다(할당 연산). 이때는 참조 값이 아니라 함수 만 받아서 전달하기 때문에 this
정보가 사라진다. obj.method()
같이 점을 사용하거나, obj[method]()
같이 대괄호를 사용해 함수를 호출했을 때만 this
값이 의도한대로 전달된다. func.bind()
등을 이용하면 해결 하는 방법도 있긴 한다.