在JavaScript中使用.bind()时出现“Unexpected token '.'”错误

4

我刚刚尝试使用.bind()进行概念验证,但注意到如果我尝试在这段代码中使用.bind(),我会得到一个意外的标记“.”:

var myObj = {
    foo: function(){
        function bar(){
            console.log(this);
        }.bind(this); // errors
        bar();
    }
}

myObj.foo();

然而,如果我这样做:
var myObj = {
    foo: function(){
        var bar = function(){
            console.log(this);
        }.bind(this);
        bar();
    }
}

myObj.foo();

没问题,没有错误。能否有人解释一下这种行为的原因?我猜测这可能与函数解析的时间有关,但如果有更深入的解释,那就太好了!


2
第一个版本是一个函数声明,而第二个版本是分配一个函数“值”。 - thebjorn
1个回答

4

bind()Function.prototype上的一个方法。因此,它应该在函数对象上调用,并将返回一个具有相同主体但绑定到不同值的this的新函数。

当使用函数声明(第一种情况)时,您不会得到一个函数对象作为返回值(第一种情况),因此出现错误。没有任何可调用bind()的内容。

第二个例子可以工作,因为您给变量分配了一个函数,所以您得到了一个函数对象。

考虑:

function a() {
   return this.variable;
}

a(); // === undefined, because "this" is bound to the global object, 
     // and global object does not have "variable" defined.
     // When not in strict mode, global object === window (in browser env).

var b = window.a.bind({variable: 'value'});
    // Since a() was declared, it is a property of the global object (window).
    // Lets get it and bind to some object.

b(); // === 'value' - because 'b' is essentialy 'a' bound to {variable: 'value'}.

window.variable = 'other value';  // assign variable to global object
a(); // === 'other value'
b(); // === 'value' - it is not bound to global object, so no change here.

在您的例子中,您可以这样做:

var myObj = {
    foo: function(){
        function bar(){
            console.log('this', this);
        }

        var bar2 = bar.bind(this);
        bar2();

        // Or:
        // bar.bind(this)();
    }
}

还值得注意的是,它不是一个函数表达式,因为声明具有“更高的优先级” - 要使其成为函数表达式,您应该将其分配给一个变量或使用括号。 - Qantas 94 Heavy
谢谢,我觉得我更明白它为什么能工作而不是为什么不能。我认为我需要更多地了解函数声明在幕后发生了什么。 - benhowdle89
@benhowdle89 - 当然,很高兴能帮到你。如果你想更深入地了解函数、绑定、作用域等概念,我非常推荐 Dmitry Soshinkov 的博客系列 - 仔细阅读几遍,你就能彻底掌握它们 :) - kamituel

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