call,apply,bind的比较在一个简单的例子中

时间:2016-09-26 08:13:04

标签: javascript function scope this call

  

这个问题比较了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);




结果:

enter image description here

查询:

  1. 在计划中做出哪些改变以获得结果'理查德'在第三种情况?
  2. 如果呼叫和申请做与第1和第2情况相同的事情申请超过绑定的重要性或何时使用申请以外的申请?
  3. 即使绑定返回函数,也不应该在控制台中显示obj3与此函数的一些绑定(如obj3作为参数)?

1 个答案:

答案 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

我希望这有助于为您清理它。

干杯, 吉姆