발견된 곳
function handleClick(){
console.log('button clicked')
}
OK : document.querySelector('#btn').onclick = handleClick
OK : document.querySelector('#btn').onclick = function (){ handleClick(); }
OK : documnet.querySelector('#btn').onclick = handleClick.bind();
Error : document.querySelector('#btn').onclick = handleClick()
Function.prototype.bind()
this.x = 9;
const module = {
x : 42,
getX : function(){
return this.x;
}
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX()); // 42
예제
bind()의 가장 간단한 사용법은 호출 방법과 관계없이 특정 this 값으로 호출되는 함수를 만드는 것입니다.
초보 프로그래머로서 흔한 실수는 객체로부터 메소드를 추출한뒤 그 메소드를 호출할 때, 원본 객체가 그 함수의 this로 사용될 것이라 기대하는 것입니다.
그러나 특별한 조치가 없으면, 대부분의 경우 원본 객체는 영향을 끼치지 않습니다.
원본 객체가 바인딩 되는 함수를 생성하면 이러한 문제를 깔끔하게 해결할 수 있습니다.
this.x = 9;
var module = {
x : 81,
getX : function (){
return this.x;
}
}
module.getX() // 81
var retrieveX = module.getX;
retrieveX() ; // 9 , 함수가 전역 스코프에서 호출되어서 전역 변수 호출
var boundGetX = retrieveX.bind(module)
boundGetX(); // 81
module과 바인딩된 'this'가 있는 새로운 함수 생성
신입 프로그래머는 전역 변수 x 와 module의 속성 x 를 혼동할수 있음.
bind() 의 다음으로 간단한 사용법은 미리 지정된 초기 인수가 있는 함수를 만드는 것입니다. 지정될 초기 인수가 있다면 제공된 this 값을 따르고, 바인딩 된 함수에 전달되어 바인딩 된 함수가 호출될 때마다 대상 함수의 인수 앞(첫번째 인자라고 생각해야 할듯)에 삽입됩니다.
function list(){
return Array.prototype.slice.call(arguments);
}
// slice.call 의 의미가 누적인듯?
var list1 = list(1,2,3); // [1,2,3]
var leadingThirtysevenList = list.bind(null, 37)
var list2 = leadingThirtysevenList() ; // [37]
var list3 = leadingThirtysevenList(1,2,3); [37,1,2,3]
function addArgumenet(args1, args2){
return args1 + args2
}
var result1 = addArgumenet(1,2); // 3
var addThirtySeven = addArgumenet.bind(null, 37);
var result2 = addThirtySeven(5) // 37+5 = 42
var result3 = addThirtySeven(5,10) // 37+5 = 42
window.setTimeout() 내에서 기본으로, this 키워드는 window 객체로 설정됩니다.
클래스 인스턴스를 참조하는 this를 필요로 하는 클래스 메소드로 작업하는 경우, 명시해서 this를 콜백 함수에 바인딩할 수 있습니다.
function LateBloomer (){
this.petalCount = Math.ceil(Math.random() * 12) + 1
}
// 1초 지체 후 bloom 선언
LateBloomer.prototype.bloom = function(){
window.setTimeout(this.declare.bind(this), 1000)
}
LateBloomer.prototype.declare = function(){
console.log('i am a beautiful flower with ' + this.petalCount + ' petals!');
}
var flower = new LateBloomer();
flower.bloom(); // 1초 뒤 'declare' 메소드 유발하여
i am a beautiful flower with 8 petals! 출력
새로운 인스턴스를 생성했으니 원래는 this.petalCount 라는 변수에
접근을 못하나 bind(this)를 해서 엮어줌으로써
새로운 인스턴스에서도 원본 클래스에 있는
this.petalCount 부분에 접근할 수 있다.