简单例子中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);
结果:
查询:
- 要在第 3 种情况下获得 'Richard' 的结果,需要对程序进行哪些更改?
- 如果 call 和 apply 做的事情与第一种和第二种情况相同,那么 apply 比 bind 有什么重要性,或者什么时候使用 apply 而不是 call?
- 即使绑定 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
我希望这有助于为您解决问题。
干杯,
吉姆
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);
结果:
查询:
- 要在第 3 种情况下获得 'Richard' 的结果,需要对程序进行哪些更改?
- 如果 call 和 apply 做的事情与第一种和第二种情况相同,那么 apply 比 bind 有什么重要性,或者什么时候使用 apply 而不是 call?
- 即使绑定 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
我希望这有助于为您解决问题。
干杯, 吉姆