这个问题比较了3种方法的回报,而不是通过正常的IIFE函数返回来比较这是如何做到的。
这个简单的例子显示了使用范围绑定方法(即viz - call,apply和bind)实现的结果的比较。
代码段
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);

结果:
查询:
答案 0 :(得分:1)
所有三个结果变量都是引用函数,因此这些变量本身就是函数。当您使用bind方法时,您将分配printName函数以在事实之后执行,而call和apply方法立即运行。为了得到理查德"从result3返回你只需要调用它作为这样的函数:result3();尝试以相同的方式运行result1()或result2()将显示错误,因为这些方法是动态应用的,并且在事后不可用作函数。
读取此行时:
var result1 = printName.call(obj1);
...然后立即运行printName函数,并将该函数返回的值赋给result1。结果相同。
读取此行时:
var result3 = printName.bind(obj3);
...然后将函数本身分配给result3,可以通过键入
来运行result3();
所以call和apply用于获取返回值,而bind用于获取返回的函数。
关于call和apply,由于你的任何对象或原型方法中没有任何引用到THIS关键字,你不需要传入重新定义的THIS上下文。当您需要更改属于另一个对象的方法的上下文时,Call和Apply方法通常是最佳的。看一下向obj1添加新方法的扩展示例:
obj1.sayHello = function() {
console.log('Hello ' + this.name);
}
obj1.sayHello() //returns "Hello Peter"
如果你想在obj1中使用sayHello方法来显示来自obj2的数据,那么你就可以使用这个或者像这样申请:
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
我希望这有助于为您清理它。
干杯, 吉姆