今天被问到了一个有关javascript中的call()和apply()的一个问题,当时看书的时候,也有一定的了解,但是理解的不是很透彻,所以又学习了一下,把书上的例子拿来用一用,加深理解!总结如下:
- 每个函数都有两个非继承而来的方法:call()和apply();这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。apply()方法接收两个参数,一个是在其中运行函数的作用域,另一个是参数数组(可以是Array的实例,也可以是arguments对象。)举个例子:
***//使用apply()或call()改变this的指向***
function sum(num1,num2){
return num1+num2;
}
function callsum1(num1,num2){
**//传入arguments对象,此时this指向sum这个对象,js中的函数也是一个对象**
return sum.apply(this,arguments);
}
//传入数组
function callsum2(num1,num2){
return sum.apply(this,[num1,num2]);
}
alert(callsum1(10,10)); //20
alert(callsum2(10,10)); //20
**// add对象替换sub对象,add.call(sub,3,1) == add(5,2) ,所以运行结果为7**
function add(a, b){
console.log(a + b);
}
function sub(a, b){
console.log(a - b);
}
add.call(sub, 5, 2);
**//使用call()或是apply()实现继承**
function Person1() {
this.name = "Tom";
this.showName = function() {
console.log(this.name);
}
}
function Person2() {
this.name = "Andy";
}
var peo1 = new Person1();
var peo2 = new Person2();
peo1.showName.call(peo2); //Andy
/*peo2这个构造函数中没有showName()这个方法,但是使用call()后,
*peo2就继承了peo1中的showName()方法;
*/
call()方法与apply()方法的作用相同,区别仅在于接收参数的方式不同。call(),第一个参数是this值没有变化,变化的是其余参数都直接传递给函数,在使用call()方法时,传递给函数的参数必须逐个列举出来。例如:
function sum(num1,num2){
return num1+num2;
}
function callsum(num1,num2){
return sum.call(this,num1,num2);
}
alert(callsum(10,10)); //20
至于是使用 apply()还是 call(),完全取决于你采取哪种给函数传递参数的方式最方便.
传递参数并非apply()和call()真正的用武之地,它们真正强大的地方是能够扩充函数赖以运行的作用域。例如
window.color="red";
var o={color:"blue"};
function sayColor(){
alert(this.color);
}
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
此例中,sayColor()是作为全局作用域函数定义的,在全局作用域中调用它,结果为red,
this.color转换成window.color. sayColor.call(this)和sayColor.call(window),则是两种显式地在全局作用域中调用函数的方式,结果显示red.当运行sayColor.call(o)时,函数的执行环境就不一样了,此时函数体内的this指向 o,于是结果显示blue.使用call()或者apply()来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。