JS里的this绑定中硬绑定后为什么不能再修改this的指向?

在this的绑定方式中,有一种称为硬绑定的方式,如下:


    var a = 5;
    function foo() {
        console.log(this.a);
    }
    var obj = {
        a: 2
    };
    var bar = function() {
        foo.call(obj);
    };
    bar();
    setTimeout(bar, 100);
    //为什么再次显示绑定失败?
    bar.call(window);  //输出2

三次都输出2
前两个我能大概解释下,创建了一个匿名函数,该函数每次调用都会用call()方法显示的把foo的this绑定到Obj上,然后把它赋值给bar,所以每次调用bar()函数this指向obj,即使在setTimeout中也没有发生this绑定丢失情况

我的问题是:在bar()函数中再次用call()方法把想要把this指向window对象,可是却失败了..为什么?

我的想法是:是不是在bar.call(window)时先把this指向了window,然后因为间接引用了匿名函数又把this指向修改成了obj,所以输出了2?

我想知道最后一行bar.call()调用时发生的详细过程,谢谢。

阅读 4k
3 个回答

bar的this和foo的this有什么关系?

var test=this; 先把this赋给变量,这样方便改

题主写的代码是《你不知道的JS(上)》P88 页的片段。这一段代码是 创建一个包裹函数bar(),传入所有的参数并返回接收到的所有值。用这种方式实现一个硬绑定(绑定一次后 this 的指向就无法使用隐式绑定或者显式绑定来修改 this),解决P85页提到的 隐式丢失 问题。
第一次看到这段代码的时候也有类似题主的这种疑惑,明明是两个this,一个this在函数内部被绑定了,再怎么绑定外部的this都不会影响内部函数的this指向。再回头看下作者写这段 显示硬绑定代码 的用心就懂了。

由于硬绑定是一种非常常用的模式,所以在 ES5 中提供了内置的方法 Function.prototype.bind

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题