JavaScript 的 bind 方法似乎不能按预期工作

3

var obj = {
    say: function() {
        function _say() {
            console.log(this);
        }
        return _say.bind(obj);
    }()
};

obj.say();

代码的结果是注销全局或窗口,我想知道为什么bind方法没有将“this”绑定到obj对象上下文?


这里真正的问题是,如果你需要 this 绑定,为什么不使用一个带有原型的实际对象呢?你展示的代码试图将“实例逻辑”倾入“无实例”的代码中,虽然你可以这样做,因为它是JavaScript,但这也太...愚蠢了吧?你实际上想用这段代码做什么?(或者类似这样的代码) - Mike 'Pomax' Kamermans
(1) 在 return _say.bind(obj); 行上设置一个断点。 (2) 当它停在那里时,检查 obj 的值。 (3) 认真思考。 (4) 向你的 橡皮鸭 解释为什么你要将 IIFE 的结果分配给属性 say - user663031
感谢您的评论,@Mike 'Pomax' Kamermans。这段代码只是练习,我想知道为什么在使用bind(undefined)时'this'是全局的。 - smallbone
如果你在进行特定领域的深入研究,那么这是一个合理的问题。但是,你展示的代码不值得在任何真实文件中使用,更糟糕的是,让其他人来处理它 =) - Mike 'Pomax' Kamermans
2个回答

1
在赋值期间,变量obj仍然没有任何值。因此,您对bind的调用相当于.bind(undefined),其行为与您观察到的相同。
更具体地说,this引用window是因为OrdinaryCallBindThis执行以下步骤(非严格模式):
[...]
If thisArgument is undefined or null, then
[...]
Let thisValue be globalEnvRec.[[GlobalThisValue]].

你可以在Chrome调试器中检查,发现在你的调用后[[BoundThis]]确实是undefined

感谢您的回答,@ASDGerte。但是,如果_say函数将'this'绑定到'undefined',为什么obj.say()中的'this'会绑定到全局/窗口,而不是obj? - smallbone
@smallbone编辑了。我也回答后正在搜索那个 :) - ASDFGerte
我明白了!非常感谢。 - smallbone

0
你正在立即调用这个函数。移除say函数后面的括号。如果你希望在没有两个连续括号obj.say()()的情况下调用该函数,请使用.call()而不是.bind()

var obj = {
  say: function() {
    function _say() {
      console.log(this);
    }
    return _say.call(this);
  }
};

obj.say();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接