1. 사라진 this....
setTimeout 에 메서드를 전달할 때 처럼, 객체 메서드를 콜백으로 전달할 때 'this 정보가 사라지는' 문제가 생긴다.
(객체 메서드가 객체 내부가 아닌 다른 곳에 전달되어 호출되면 this 가 사라진다.)
let user = {
firstName: "John",
sayHi() {
alert(`Hello, ${this.firstName}!`);
}
};
setTimeout(user.sayHi, 1000);
//원래는 John이 출력되어야함
하지만 alert창엔 undefined가 출력된다.
--> setTimeout에 객체에서 분리된 함수인 user.sayHi가 전달되기 때문이다.
(브라우저 환경에서 setTimeout 메서드가 동작하는 방식은 인수로 전달받은 함수를 호출할 때, this에 window를 할당한다.)
2. this 살리기 방법. 래퍼
래퍼함수를 사용한다.
let user = {
firstName: "John",
sayHi() {
alert(`Hello, ${this.firstName}!`);
}
};
setTimeout(function() {
user.sayHi();
}, 1000);
--> 래핑 된 function()이 외부 렉시컬 환경에서 user를 받아서 메서드를 호출 했다. (외부 렉시컬 환경은 let으로 정의한 user객체 이기 때문에 this가 객체를 가리키게 됨.)
**하지만 이 방법을 쓰면 setTimeout이 트리거 되기 전에 user가 변경되었을 때, 변경된 객체의 메서드를 호출하게 된다.(취약성이 생김)
3. this 살리기 방법. bind
모든 함수는 this를 수정하게 해주는 내장 메서드 bind를 제공한다.
let boundFunc = func.bind(context);
//기본문법
let user = {
firstName: "Ssun"
};
function func() {
alert(this.firstName);
}
let funcUser = func.bind(user);
funcUser();
// Ssun
--> func.bind(context)는 '특수객체'를 반환한다. 이 객체를 호출하면 this가 context로 고정된 함수가 반환됨.
위 예시에서는 this가 user로 고정됨.
let user = {
firstName: "Ssun",
sayHi() {
alert(`Hello, ${this.firstName}!`);
}
};
let sayHi = user.sayHi.bind(user);
sayHi();
// Hello, John!
setTimeout(sayHi, 1000);
// Hello, John!
user = {
sayHi() { alert("또 다른 사용자!"); }
};
//1초 내에 user값을 변형해도 sayHi는 기존 값을 사용한다.
--> user값을 변형해도 sayHi는 기존 값을 그대로 사용하는데, (*)줄에서 sayHi가 '묵인(bound)' 함수가 되어 고정되기 때문이다.
3. 부분적용
this 뿐만 아니라 전달되는 인수도 바인딩이 가능하다.
let bound = func.bind(context, [arg1], [arg2], ...);
//기본 문법
function mul(a, b) {
return a * b;
}
let boundMul = mul.bind(null, 2);
//context가 null, 첫번째 인수가 2인 새로운 함수 boundMul
console.log(double(3))
//2*3 = 6. 첫번째 인수를 2로 묶어놓은 것.
'Front-end > JavaScript' 카테고리의 다른 글
[JavaScript] 프라미스화 Promisfication (0) | 2022.05.29 |
---|---|
[JavaScript] this & argument가 없는 화살표 함수 (0) | 2022.05.09 |
[JavaScript] 데코레이터 ((미완)) (0) | 2022.05.09 |
[JavaScript] setTimeout과 setInterval을 이용한 호출 스케줄링 (0) | 2022.05.09 |
[JavaScript] new Function (0) | 2022.05.09 |