참조 타입에 대해 설명해주세요 (feat. obj.method를 할때 자바스크립트에서는 어떤일이 발생할까)
https://ko.javascript.info/reference-type
복잡한 상황에서 메서드를 호출하면 this값을 잃어버리는 경우가 있다.
let user = {
name: "John",
hi() {alert(this.name);},
bye() {alert('Bye');}
}
user.hi(); // John
(user.name === "John" ? user.hi : user.bye)(); // Error
마지막 줄에서 조건부 연산자를 사용해서 user.hi나 user.bye중 하나가 호출되도록 했는데, 어떤건 정상적으로 호출이 되었고, 어떤건 에러가 발생했다.
user.hi();
는 정상적으로 호출이 되었고
(user.name === "John" ? user.hi : user.bye)();
여기서는 에러가 발생했다.
원인이 무엇일까?
참조 타입 자세히 알아보기
obj.method를 할때 자바스크립트에서는 어떤일이 발생할까
.
을 통해서 obj.method를 통해 객체 프로퍼티에 접근한다.()
는 접근한 프로퍼티(메서드)를 실행한다.
위 동작으로 실행하는데,
user.hi();
는 어떻게 this가 제대로 전달되었을까?
let hi = user.hi;
hi(); // Error
위 코드는 왜 this가 제대로 전달되지 않았을까?
왜냐하면 '.'이 함수가 아닌 참조타입값을 반환하기 때문이다.
참조 타입은 명세서에서만 사용되는 타입으로 개발자가 실제로는 사용할 수 없다.
참조 타입은 다음과 같은 3가지 조합으로 이루어져 있다.
- base: 객체
- name: 프로퍼티 이름
- strict: 엄격모드에서 true
즉, user.hi
로 프로퍼티에 접근하면, 함수가 아닌 참조 타입을 반환한다.
엄격 모드인 경우, 다음과 같이 반환된다.
(user, hi, true)
이런 참조형 값에 ()
를 붙여서 호출하면 객체의 메서드와 연관된 모든 정보를 받는다. 이 정보를 기반으로 this(user)가 결정된다.
즉, 참조 타입은 .
연산에서 알아낸 정보를 ()
로 전달해주는 중개인 역할을 하는 것이다.
근데, 점 연산 이외의 연산(할당 연산 등)은 참조타입을 통째로 버리고 user.hi
값만 받아서 전달한다.
그렇기 때문에 점 이외의 연산에서는 this정보가 사라진다.
즉,
obj.method();
(obj.method)();
obj[method]();
위와 같은 코드에서는 참조 타입을 사용하여 this값이 의도한 대로 전달되지만
a = obj.method;
a();
위 처럼 할당 연산을 하게되면 참조 타입을 버리므로, this가 원하는대로 전달되지 않는다. 이런경우는 bind
를 사용하여 해결할 수도 있다.
let obj, method;
obj = {
go: function() { alert(this); }
};
obj.go(); // (1) [object Object]
(obj.go)(); // (2) [object Object]
(method = obj.go)(); // (3) undefined => 할당 연산때문
(obj.go || obj.stop)(); // (4) undefined => 그냥 메서드 호출 연산빼고 모두 참조 타입을 버린다고 생각하자.
'개발 > FrontEnd Interview' 카테고리의 다른 글
CI, CD의 개념 (0) | 2021.08.14 |
---|---|
Shadow DOM이 아니라 Iframe를 사용한 이유 (2) | 2021.07.21 |
모듈이란? feat. 일반스코프와 모듈의차이 (0) | 2021.06.28 |
Tagged Template Literals (feat. styled-component) (1) | 2021.06.27 |
prettier와 eslint의 차이가 뭔가요? (0) | 2021.06.27 |