apply()和call()等于设置函数体内this的值,即改变对象的this指向的内容。这在面向对象的js编程过程中有时是很有用的。 ?也可以说是为了改变函数体内部 this 的指向。
首先apply() 方法接收2个参数: 一个是在其中运行函数的作用域(可以用this),另一个是参数数组。其中第二个参数可以是Array的实例,也可以是arguments对象,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function sum(num1,num2){ return num1 + num2; } function callSum1(){ return sum.apple(this,arguments); // 传入arguments 对象 } function callSum2(){ return sum.apple(this,[num1,num2]); // 传入数组 } alert(callSum1(10,10)); // 20; alert(callSum2(10,10)); // 20; |
callSum1() 在执行sum() 函数执行时传入了this作为this 值,(因为在全局作用域中调用的,传入的是window对象)和arguments对象。而callSum2 也同样调用了sum(),但是它传入的是this 和一个参数数组。这两个函数都会返回正确的结果。
apply() 和call() 有什么不同?
call() 和apply() 方法作用相同,他们的区别仅在于接收的参数不同。对于call()方法而言,第一个参数是this值没有变化,变化的是其余参数都是直接传递给数组,在传递的时候,参数必须逐一个列出来。
1 2 3 4 5 6 7 8 9 |
function sum(num1,num2){ return num1 + num2; } function callSum(){ return sum.call(this,num1,num2); } alert(callSum(10,10)); // 20 |
使用哪一种完全取决于那一种使用起来方便
call()和apple()他们真正强大的地方是能够扩充函数赖以生存的作用域
1 2 3 4 5 6 7 8 9 10 11 |
window.color = "red"; var o = {color:"blue"}; function sayColor(){ return this.color; } sayColor(); // red; sayColor(this); // red; sayColor(window); // red; sayColor.call(o); // blue; // 对象指向了0,于是就得到了blue |
还有另外一个方法 bind() ; // 这个方法会创建一个函数实例,其this值会被绑定传递给this() 函数的值
下面附上一个实例,关于this 关键字,和 call()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var name = "window"; var Bob = { name: "Bob", showName: function(){ alert(this.name); } }; var Tom = { name: "Tom", showName: function(){ var fun = Bob.showName; fun(); } }; Tom.showName(); // window |
这里为什么输出window?
当a对象的方法被赋予b对象,该方法就变成了普通函数,其中的this就从指向a对象变成了指向b对象。
那我们来看看
1 2 |
var fun = Bob.showName; fun(); |
上面这段代码中showName方法赋予了fun对象,我们调用的不再是Bob对象的showName方法,而是fun方法。fun实际上是window对象的一个属性(方法)。所以,fun方法的上下文环境是什么?window对象。
实际上相当于这个效果
1 2 3 4 5 6 7 |
var name = "window"; var fun = function() { alert(this.name); }; window.fun(); |
那么,如何输出Bob?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var name = "window"; var Bob = { name: "Bob", showName: function(){ alert(this.name); } }; var Tom = { name: "Tom", showName: function(){ var fun = Bob.showName(); } }; Tom.showName(); //Bob |
使showName方法运行时仍处在Bob对象的环境中
话说,为什么会想要输出Tom?想输出Tom就不应该调用Bob的方法啊 – –
直接alert(this.name)不就好了
强行要用的话,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var name = "window"; var Bob = { name: "Bob", showName: function(){ alert(this.name); } }; var Tom = { name: "Tom", showName: function(){ var fun = Bob.showName.call(Tom); } }; Tom.showName(); //Tom |
PS: 在通过call() 或 apply() 改变函数执行环境的情况下,this 就会指向其他对象