【问题标题】:Comparison of call, apply, bind in a simple example简单例子中call、apply、bind的比较
【发布时间】:2016-09-26 08:13:04
【问题描述】:

这个问题比较了 3 种方法的返回,而不是比较如何通过普通的 IIFE 函数返回轻松完成。

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

片段:

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. 在程序中进行哪些更改才能在第三种情况下获得“Richard”的结果?
  2. 如果 call 和 apply 与第一种和第二种情况下的操作相同,那么 apply 优于 bind 或何时使用 apply 而不是 call 的重要性是什么?
  3. 即使绑定返回函数,该函数不应该在控制台中显示 obj3 与此函数的某些绑定(如 obj3 作为参数)吗?

【问题讨论】:

  • 您能解释一下这与您之前的问题有何不同吗? Using call in JavaScript vs Returning by simple function 似乎已经讨论了差异。
  • 本题基本比较了3种方式;前面是比较普通函数和调用方法的。
  • 前两个问题都在您上一个问题的答案中得到了回答。
  • 你可以通过调用它来制作result3 == "Richard" - var result3 = printName.bind(obj3)();
  • 每个帖子只问一个问题。

标签: javascript function scope this call


【解决方案1】:

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

当这行被读取时:

var result1 = printName.call(obj1);

...然后 printName 函数立即运行,并且从该函数返回的值分配给 result1。 result2 也一样。

当这行被读取时:

var result3 = printName.bind(obj3);

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

result3();

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

关于调用和应用,由于在任何对象或原型方法中都没有对 THIS 关键字的任何引用,因此不需要传入重新定义的 THIS 上下文。当您需要更改属于另一个对象的方法的上下文时,调用和应用方法通常是最好的。看看这个向 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

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

干杯, 吉姆

【讨论】:

    猜你喜欢
    • 2012-05-02
    • 2022-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多