4

在下面的代码中,第一个函数没有绑定到obj,但第二个函数是,所以f()返回fifi并按预期g()返回。Mark Twain但是第三次​​尝试,是by (obj.getCallBack)first,现在是一个函数,然后调用它,本质上应该和fcase一样。但他们确实打印出来Mark Twain。为什么他们不一定要obj使用bind()但仍然通过this指向来执行obj

(第四次尝试只是一个通常的方法调用,并且this应该绑定到调用该方法的对象)。

(在当前的 Chrome、Firefox 和 IE 9 上测试)

window.name = "fifi";

var obj = {
    name: "Mark Twain",
    getCallBack: function() {
        return this.name;
    }
}

var f = obj.getCallBack;
var g = f.bind(obj);

console.log(f);
console.log(f());

console.log(g);
console.log(g());

console.log((obj.getCallBack)());
console.log(obj.getCallBack());
4

2 回答 2

4

您忘记了,如果函数作为某个对象的属性被调用,则该对象将是this调用的对象。所以:

obj.getCallBack() //The function referenced by `obj.getCallBack`
                    //is called as a property of `obj`, so obj will be `this`
                    //for the call

f()    //The function referenced by f, is not called as a property of some object so
         //`this` will depend on strict mode.

在这些基本规则之后,将调用绑定函数,可以将其视为代理函数(任何 shim 都会这样做),用于.call/.apply显式设置目标函数的上下文。所以this代理函数的值无关紧要,但在幕后它是由基本规则设置的。

编辑:

(obj.getCallBack) 不将函数作为值返回,因为未调用 getValue。. obj.getCallback所以它与第一篇文章完全相同。

所以你可以这样做并且不会出错:

(obj.getCallback) = 5;

相对于:

(function(){}) = 5; //invalid assignment
于 2012-10-03T12:02:37.810 回答
0

为了补充 Esailija 的回答,实际效果应该是:

var obj = {
    name: "Mark Twain",
    getCallBack: function() {
        return function() { return this.name; };
    }
}

var f = obj.getCallBack();
var g = f.bind(obj);

console.log(f);
console.log(f());

console.log(g);
console.log(g());

console.log((obj.getCallBack())());
console.log(obj.getCallBack()());

console.log(obj.getCallBack().bind(obj)());

然后在这种情况下,第三次尝试将给出fifi,第四次尝试也将给出。为了得到里面的名字obj,第五次尝试绑定它并调用它,然后会得到Mark Twain

但是返回callBack函数的方法应该绑定它,所以我们把代码改成:

var obj = {
    name: "Mark Twain",
    getCallBack: function() {
        return (function() { return this.name;}).bind(this);  // <-- note here
    }
}

现在所有的尝试,甚至f(),都将返回Mark Twain

于 2012-10-03T12:37:43.257 回答