this는 this를 사용하고 있는 함수가 어떻게 불리느냐에 따라 가리키는 값이 달라진다.
bind 메서드를 이용해서 이런 this를 원하는 값으로 바꿀 수 있다.
이 bind 메서드에 대한 것을 알아보자.
bind method
bind() 메서드는 this가 bind에 제공된 값으로 설정된 새로운 함수를 생성한다. 이 새로운 함수의 인자값을 순서대로 지정할 수도 있다.
예제로 이해해보자.
1) bind 메서드로 this가 가리키는 값 변경하기.
var healthObj = {
name : "달리기",
lastTime : "PM10:12",
showHealth : function() {
setTimeout(function(){
console.log(this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요");
}, 500);
}
}
healthObj.showHealth();
위 코드를 실행하면 500ms 뒤에 '달리기님, 오늘은 PM10:12에 운동을 하셨네요'가 출력될 것 같지만, 여기서 this.name과 this.lastTime의 결과는 undefined이다.
setTimeout은 비동기 함수로, 이 setTimeout이 실행될 땐 showHealth 함수는 이미 반환이 된 상태이다. 즉, setTimeout 안의 this는 window 객체를 가리키게 된다. window.name과 window.lastTime은 없기 때문에 undefined라는 결과가 나오는 것이다.
의도한 대로 this가 healthObj를 가리키게 하려면 bind 메서드를 사용하면 된다.
var healthObj = {
name : "달리기",
lastTime : "PM10:12",
showHealth : function() {
setTimeout(function(){
console.log(this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요");
}.bind(this), 500);
}
}
※ 참고 : function 뒤에 .이 붙어 호출되면 그 function은 객체로 변하고, function 네이티브 객체에 들어있는 메서드들을 부를 수 있다. 그 중 하나가 bind 메서드이다.
setTimeout의 콜백 함수 뒤에 .bind(this)를 붙였다.
bind로 새 함수가 생성되고, 그 안의 this를 bind의 인수로 들어오는 값으로 바꾸어 리턴한다.
bind 함수가 실행되는 시점의 this는 healthObj를 가리키므로, bind(this)의 this는 healthObj를 가리키고 있다. 그렇게 setTimeout의 콜백 함수는 healthObj를 가리키는 this를 가진 새로운 함수가 되었다.
실제로 bind 메서드를 붙인 코드로 healthObj.showHealth()를 실행해보면 '달리기님, 오늘은 PM10:12에 운동을 하셨네요'가 출력된다.
※ 주의 : arrow 함수는 this를 새로 정의하지 않고, 자신을 둘러싼 함수의 this와 같은 값을 가진다.
var healthObjWithArrow = {
name : "달리기",
lastTime : "PM10:12",
showHealth : function() {
setTimeout(()=>{
console.log(this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요");
}, 500);
}
}
healthObjWithArrow.showHealth();
//결과 값: 달리기님, 오늘은 PM10:12에 운동을 하셨네요
2) 함수의 인수를 미리 지정하기
function addArguments(arg1, arg2) {
return arg1 + art2;
}
var result = addArguments(1, 2); // 결과 값: 3
addArguments의 첫 번째 인수를 37로 지정하고 싶을 때, bind 메서드를 사용하여 해결할 수 있다.
var addThirtySeven = addArguments.bind(null, 37);
var result2 = addThirtySeven(5); //결과 값: 42
bind 첫 번째 인수는this에 전달할 값인데, addArguments 함수에는 전달받을 this가 없으므로 null을 주었다.
그 다음 인수부터 초기 값으로 지정하고 싶은 값을 순서대로 넣으면 되는데, 첫 번째 인수만 지정하고 싶으므로 37 하나만 입력한다.
bind로 새로 생성한 함수를 addThirtySeven에 저장하여 호출할 때, 인수에 5를 넣어 호출한다.
첫 번째 인수는 37로 지정되어 있고, 새로 받은 인수는 두 번째 인수로 들어가, 37 + 5 = 42를 리턴하게 된다.
만약 bind로 첫 번째 인수를 지정해준 addThirtySeven의 인수를 두 개로 전달하면 어떻게 될까?
var result3 = addThirtySeven(5, 10); //결과 값: 42
두 번째 인수는 무시되고, 앞의 한 개의 인수만 받아 지정된 값과 더한다.
출처)
edwith 부스트코스 웹 프로그래밍
MDN bind()
MDN Arrow functions
'JavaScript' 카테고리의 다른 글
자바스크립트 템플릿 라이브러리 - handlebars (0) | 2019.08.09 |
---|---|
자바스크립트 라이브러리 (0) | 2019.08.08 |
객체 리터럴과 this (0) | 2019.08.04 |
자바스크립트 배열의 함수형 메서드 (0) | 2019.08.04 |
HTML templating (자바스크립트로 템플릿 사용하기) (0) | 2019.08.03 |
댓글