在javascript中复合使用bind(this)

时间:2018-05-01 15:06:52

标签: javascript

我是javascript的新手,我正在尝试实现一个复杂的数据结构,需要修改各种函数内的范围。然后,我遇到了function.prototype.bind()。起初,我认为它非常有用。但是,有些结果是出乎意料的。所以,我写了一个测试的演示代码,这是代码。

(function () {

    this.t = 9.8765432

    this.a = (function(){
        this.t = 3.14159
        this.b = (function(){return this.t;}).bind(this)
        this.c = (function(){
            this.t=1.23456
            this.d=(function(){return t;}).bind(this)
            return this
        })()
        return this
    })()

    console.log(this.a.b()) //My guess was 3.14159, at the end it is 1.23456
    console.log((this.a.b.bind(this))()) //My guess was 9.8765432, at the end it is 1.23456
    console.log(this.a.c.d()) //My guess was 1.23456, at the end it is 1.23456
    console.log((this.a.c.d.bind(this))()) //My guess was 9.8765432, at the end it is 1.23456

    return this
})();

可悲的是,我猜错了所有结果。这表明我对此功能缺乏足够的了解。任何人都可以向我解释一下吗?

1 个答案:

答案 0 :(得分:3)

您没有为this创建任何对象来引用。因此,this只是在代码中的任何地方引用全局window对象(在严格模式下它将是undefined)。由于您只有一个对象,因此您只有一个t属性,该属性最近被赋值为1.23456。之前的作业被最近的作业覆盖。

在每个范围内使用new关键字而不是IIFE尝试测试。这将为不同范围的this创建三个单独的对象,而不是使用全局对象:

new function () {

    this.t = 9.8765432

    this.a = new function(){
        this.t = 3.14159;
        this.b = function(){return this.t;}.bind(this);
        this.c = new function(){
            this.t = 1.23456;
            this.d = function(){return this.t;}.bind(this);
            return this;
        };
        return this;
    };

    console.log( this.a.b() ); // My guess was 3.14159
    console.log( this.a.b.bind(this)() ); // My guess was 9.8765432
    console.log( this.a.c.d() ); // My guess was 1.23456
    console.log( this.a.c.d.bind(this)() ); // My guess was 9.8765432

    return this;
};

您的第一次和第三次猜测都是正确的。如果函数尚未绑定,那么您的第二次和第四次猜测将是正确的。在已绑定的函数上调用bind对它没有影响。删除内部调用bind将为您提供您期望的内容:

new function () {

    this.t = 9.8765432

    this.a = new function(){
        this.t = 3.14159;
        this.b = function(){return this.t;};
        this.c = new function(){
            this.t = 1.23456;
            this.d = function(){return this.t;};
            return this;
        };
        return this;
    };

    console.log( this.a.b() ); // My guess was 3.14159
    console.log( this.a.b.bind(this)() ); // My guess was 9.8765432
    console.log( this.a.c.d() ); // My guess was 1.23456
    console.log( this.a.c.d.bind(this)() ); // My guess was 9.8765432
    
    return this;
};