2

我运行下面的 JS 脚本,但只是发现func2()输出是foobar,不是George,谁能解释为什么func2 = func.bind(someuser)不绑定someuserfunc

var someuser = {
    name: 'George',
    func: function () {
        console.log(this.name);
    }
};
var foo = {
    name: 'foobar'
};
func = someuser.func.bind(foo);
func(); // output foobar
func2 = func.bind(someuser);
func2(); //output foobar
4

3 回答 3

4

来自MDN

bind() 函数创建一个新函数(绑定函数),其函数体(ECMAScript 5 术语中的内部 Call 属性)与正在调用它的函数(绑定函数的目标函数)相同,并且 this 值绑定到bind() 的第一个参数,不能被覆盖

基本上这意味着您不能在已绑定的函数上调用 bind。

在您的示例中,您必须执行以下操作:

func2 = someuser.func.bind(someuser);
于 2013-07-16T04:42:50.393 回答
2

我认为您想要的是弱绑定:

function weakBind(functable, context) {
    var GLOBAL = this;

    return function () {
        return functable.apply(this === GLOBAL ? context : this, arguments);
    };
}

现在你可以这样做:

var someuser = {
    name: 'George',
    func: function () {
        console.log(this.name);
    }
};

var foo = {
    name: 'foobar'
};

var func = weakBind(someuser.func, foo);
func(); // output foobar

var func2 = weakBind(func, someuser);
func2(); //output George

查看演示:http: //jsfiddle.net/R79EG/


普通绑定的问题在于,一旦将对象绑定到this指针,它就不能被覆盖。弱绑定检查this指针是否设置为GLOBAL对象(在这种情况下使用默认值)。否则,它会使用新this指向的任何内容。


顺便说一句,在您的情况下,最好这样做:

var someuser = {
    name: 'George',
    func: function () {
        console.log(this.name);
    }
};

var foo = {
    name: 'foobar'
};

var func = someuser.func.bind(foo);
func(); // output foobar

var func2 = someuser.func.bind(someuser);
func2(); //output George

这比weakBindcallfunc2会 call funcwhich 会call 更好someuser.func。但是使用bind,调用func2将直接调用someuser.func

于 2013-07-16T04:49:10.120 回答
0

你已经绑定了someuser.func

您可能希望以不同的方式设置脚本。

或使用:

func = someuser.func.bind(foo);
func(); // output foobar
func2 = someuser.func.bind(someuser);
func2(); //output foobar

不要尝试重新绑定已经绑定的函数。

于 2013-07-16T04:42:23.460 回答