简单例子中call、apply、bind的比较

Comparison of call, apply, bind in a simple example

This question compares the return by the 3 methods rather than comparing how this can be done easily by a normal IIFE function return.

这个简单的示例显示了使用范围绑定方法(即调用、应用和绑定)获得的结果的比较。

片段:

function printName() {
  return this.name;
}

var obj1 = { name: 'Peter' };
var obj2 = { name: 'John'};
var obj3 = { name: 'Richard' };

var result1 = printName.call(obj1);
var result2 = printName.apply(obj2);
var result3 = printName.bind(obj3);

console.log(result1);
console.log(result2);
console.log(result3);

结果:

查询:

  1. 要在第 3 种情况下获得 'Richard' 的结果,需要对程序进行哪些更改?
  2. 如果 call 和 apply 做的事情与第一种和第二种情况相同,那么 apply 比 bind 有什么重要性,或者什么时候使用 apply 而不是 call?
  3. 即使绑定 return 函数,该函数不应该在控制台中显示 obj3 与该函数的一些绑定(如 obj3 作为参数)?

所有三个结果变量都是引用函数,因此这些变量本身就是函数。当您使用 bind 方法时,您正在分配 printName 函数以在事后执行,而 call 和 apply 方法是 运行 立即执行。为了让 "Richard" 从 result3 返回,你只需要像这样调用它作为一个函数:result3();尝试以相同方式 运行 result1() 或 result2() 将显示错误,因为这些方法是即时应用的,事后不能作为函数使用。

读到这一行时:

var result1 = printName.call(obj1);

...然后 printName 函数立即 运行 并且从该函数返回的值被分配给 result1。结果 2 相同。

读到这一行时:

var result3 = printName.bind(obj3);

...然后函数本身被分配给 result3 并且可以 运行 通过键入

result3();

所以 call 和 apply 用于获取返回值,而 bind 用于获取返回函数。

关于调用和应用,由于您在任何对象或原型方法中都没有对 THIS 关键字的任何引用,因此您不需要传入重新定义的 THIS 上下文。当您需要更改属于另一个对象的方法的上下文时,Call 和 Apply 方法通常是最好的。看看这个向 obj1 添加新方法的扩展示例:

obj1.sayHello = function() {
    console.log('Hello ' + this.name);
}

obj1.sayHello() //returns "Hello Peter"

如果您想在 obj1 中使用 sayHello 方法来显示来自 obj2 的数据,那么您可以像这样使用 call 或 apply:

obj1.sayHello.call(obj2);  //returns "Hello John"

call 和 apply 的最大区别在于当你想将参数传递给存在于另一个对象中的函数时。因此,如果我们按如下方式更改 obj1 上的 sayHello 方法:

obj1.sayHello = function(greeting) {
    console.log(greeting + ' ' + this.name);
};

sayHello 函数现在接受一个参数。如果您再次这样调用该函数:

obj1.sayHello('Welcome'); //returns Welcome Peter

但是如果你想在 obj2 上使用这个方法,那么你会这样做:

obj1.sayHello.call(obj2, 'Greetings'); //returns Greetings John

使用call方法时,可以使用逗号分隔的字符串传入参数。您也可以以相同的方式使用 apply,只是您需要传入一个值数组作为参数,如下所示:

obj1.sayHello.apply(obj2, ['Happy Hump Day']); //returns Happy Hump Day John

我希望这有助于为您解决问题。

干杯, 吉姆