问:

下面代码中的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来达到约定俗成的效果,这时候就需要根据它的几个规则来逐一判断了。