关于Javascript中this的一点思考
问:
下面代码中的this
指代的是哪个对象?
$(document).ready(function(){
$(".TestCase").click(function (){
console.log(this.id);
});
});
答案是不确定。如果这里的$
是jQuery中的那个变量名,那么this
指代的是$(".TestCase")
所选择的对象,否则this
可能是任意对象。
好吧,我承认上面的回答有点tricky,但我主要想表达的是JavaScript里面的this
的绑定是非常灵活的(关于this
绑定的规则可查看Reading <this & Object Prototypes> - 1)。
实现1
比如以上的this
绑定为前面选择的对象可以这样实现(selectedTarget
表示上面的$(".TestCase")
):
var selectedTarget = {
id: 'the_id',
click: function (callback) {
this._click_callback = callback;
},
clickEvent: function () {
this._click_callback();
}
};
selectedTarget.click(function (){
console.log(this.id);
});
首先,click函数作为selectedTarget
对象的一个属性,在其被调用时(即selectedTarget.click(response);
),click函数中的this
表示的是调用它的对象,即selectedTarget
。这里click函数的输入为另一个函数,它会在发生click的事件(这里用selectedTarget.clickEvent
来代表这个事件接口)时被调用。所以click函数的作用就是绑定了click事件和它对应的回调函数(这里的绑定类似于this._click_callback = callback;
)。而click的输入的函数中的this
其实也是指向了selectedTarget
,因为它被调用时是这一句this._click_callback();
,已经是作为selectedTarget
的属性被调用了。
实现2
换个思路,可以使用bind
函数来显示地绑定this
到目标对象:
var selectedTarget = {
id: 'the_id',
};
function bindClickFunc(callback) {
this._click_callback = callback;
}
function callClickFunc() {
this._click_callback();
}
selectedTarget.click = bindClickFunc.bind(selectedTarget);
selectedTarget.clickEvent = callClickFunc.bind(selectedTarget);
selectedTarget.click(function (){
console.log(this.id);
});
使用bind
的好处是this
指向的对象被显式表达出来了,代码更容易理解。
实现3
以上实现都是把this
指向了调用者,这里让this
指向一个无关的对象:
var selectedTarget = {
id: 'the_id',
};
function bindClickFunc(callback) {
this._click_callback = callback;
}
function callClickFunc() {
this._click_callback();
}
var anotherObj = {};
selectedTarget.click = bindClickFunc.bind(anotherObj);
selectedTarget.clickEvent = callClickFunc.bind(anotherObj);
selectedTarget.click(function (){
console.log(this.id);
});
结论
关于JavaScript里面的this
到底指向哪个对象,由于其规则非常灵活且被封装后也无法轻易得知它的指向(可以理解为它就是run-time动态的),所以大部分使用的时候只要按照约定俗成的方式去知道这里的this是哪个对象即可(约定俗成是被调用函数的所属对象和this
绑定,即隐式绑定的结果),至于到具体实现才需要考虑怎样绑定this来达到约定俗成的效果,这时候就需要根据它的几个规则来逐一判断了。
Comments