调用apply和bind,以及它们之间的区别。
让我们使用日常术语来学习apply和call。
你有三辆车:your_scooter,your_car和your_jet
,它们都使用相同的机制(方法)启动。我们创建了一个带有方法push_button_engineStart
的对象automobile
。
var your_scooter, your_car, your_jet;
var automobile = {
push_button_engineStart: function (runtime){
console.log(this.name + "'s" + ' engine_started, buckle up for the ride for ' + runtime + " minutes");
}
}
让我们了解什么时候使用call和apply。假设您是一名工程师,拥有未配备推按钮引擎启动器的
your_scooter
、
your_car
和
your_jet
,并且您希望使用第三方
push_button_engineStart
。
如果运行以下代码行,它们将会报错。为什么?
//your_scooter.push_button_engineStart();
//your_car.push_button_engineStart();
//your_jet.push_button_engineStart();
automobile.push_button_engineStart.apply(your_scooter,[20]);
automobile.push_button_engineStart.call(your_jet,10);
automobile.push_button_engineStart.call(your_car,40);
所以上述示例成功地将汽车对象的功能赋予了你的摩托车、你的汽车和你的飞机等。
让我们深入探讨一下。在这里,我们将拆分上面的代码行。automobile.push_button_engineStart帮助我们获取正在使用的方法。
进一步地,我们使用点号表示法来使用apply或call。
现在,apply和call接受两个参数。
上面的代码中,在最后一行中,我们设置了上下文(context)。
区别在于,apply接受以数组形式的参数,而call只能接受逗号分隔的参数列表。
JS Bind函数是什么?
绑定(bind)函数基本上是将某些东西的上下文绑定并存储到变量中,以便稍后执行。
让我们使我们之前的示例变得更好。之前,我们使用属于汽车对象的方法,并用它来装备你的汽车、你的飞机和你的摩托车。现在,让我们想象一下,我们想要单独为每辆车提供一个独立的push_button_engineStart,在任何后期阶段启动我们的汽车。
var scooty_engineStart = automobile.push_button_engineStart.bind(your_scooter);
var car_engineStart = automobile.push_button_engineStart.bind(your_car);
var jet_engineStart = automobile.push_button_engineStart.bind(your_jet);
setTimeout(scooty_engineStart,5000,30);
setTimeout(car_engineStart,10000,40);
setTimeout(jet_engineStart,15000,5);
还不满意吗?
让我们把它讲得清晰明了。现在是实验的时候了。我们将回到调用和应用函数应用程序,并尝试将函数的值存储为引用。
以下实验失败,因为调用和应用是立即调用的,因此我们从未达到将引用存储在变量中的阶段,这就是绑定函数发挥作用的地方。
var test_function = automobile.push_button_engineStart.apply(your_scooter);
call()
和apply()
都是调用函数的方法,但bind()
是创建一个新的函数。使用call()
时,需要逐个传递参数;而使用apply()
时,则需将参数作为数组传入。如需了解更多细节,请查看相关文档,它们可以完整地回答你的问题。 - Nopebind()
,而另外两个函数则已存在于JavaScript 1.3 - ECMA-262第3版中,例如关于它们的问题,Stack Overflow上有像what-is-the-difference-between-call-and-apply这样的问题。我只是猜测,因为我自己也在思考这个问题。 - Nope