使用Javascript绑定立即调用方法

Immediately Invoking Methods with Javascript Bind

本文关键字:调用 方法 Javascript 绑定 使用      更新时间:2023-09-26

我正在学习Bind、Call和Apply,我有一个关于Bind的问题,但我一直无法找到好的答案:

假设我有以下代码

var Jim = {
    firstName: 'Jim',
    lastName: 'Bob',
    fullName: function() {
        return this.firstName + ' ' + this.lastName; 
    }
};
var fName = Jim.fullName; //now fName's context is window
//If I invoke fName here, I will get the expected 'undefined undefined' 
console.log(fName());

然而,我也可以执行以下操作,并在传递新上下文后立即调用绑定方法:

fName.bind(Jim)(); //this returns 'Jim Bob'

我觉得这只是在模仿callapply可以(应该)做什么。如果我在上一行之后再次调用fName(),它仍然绑定到窗口对象(fName没有被bind的就地使用所修改)。这种做法不好吗?

这个怎么样:

var Jim = {
    //same object definition as above
};
var Chris = {
    firstName: 'Chris',
    lastName: 'Smith'
};
var fName = Jim.fullName.bind(Jim); //now fName's context is the Jim object
console.log(fName()); //this will log 'Jim Bob' as expected

现在,如果我试图将绑定的方法绑定到另一个上下文,它是不起作用的:

fName.bind(Chris)(); //this still logs 'Jim Bob' from the original context

我相信在第二种情况下,这是因为我基本上是在创建一个"函数绑定边界",所以它有两个上下文,只适用于第一个上下文。

对这两个案子有什么想法吗?

你基本上是对的。进行

var fName = Jim.fullName;
fName.bind(Jim)();

和完全一样吗

var fName = Jim.fullName;
fName.call(Jim);

我不确定我会把第一个例子称为"坏做法",但它绝对不是"好做法"。call在不生成新函数值的情况下完全按照您的意愿执行,并且(在我看来)更好地描述了您的意图。

至于为什么你们不能重新绑定一个函数,你们是非常接近正确的。与其说fName有两个上下文,不如说它仍然只有一个上下文。但bind明确表示"这是该函数的上下文,毫无疑问。"

您不再像以前那样绑定到相同的fName函数。bind返回一个新的绑定函数,其this值不能被重写。

根据MDN文件,

bind()函数创建了一个新函数(绑定函数),该函数具有与其被调用的函数(绑定函数的目标函数)相同的函数体(ECMAScript 5术语中的内部调用属性),该值绑定到bind(。