js中apply和call算是一个比较绕的方法,今天我就谈谈我对它们的理解,错误之处欢迎指正。
1,语法
/* call()方法 */
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);
/*apply()方法*/
function.apply(thisObj[, argArray])
call方法是传入一个目标对象thisObj
,参数是以一个个逗号分隔的变量组成。call前面方法中this会指向thisObj
。
apply方法是传入一个目标对象thisObj
,参数是一个数组。apply前面方法中this会指向thisObj
。
2,用法
1),不带参数
function demo() {
//将参数转化成数组
var arr = Array.prototype.slice.call(arguments);
//或者
var arr1 = Array.prototype.slice.apply(arguments);
//或者
var arr2 = [].slice.call(arguments);
//或者
var arr3 = [].slice.apply(arguments);
//[].slice方法要比Array.prototupe.slice的效率更高
console.log(arr,arr1,arr2,arr3);
}
demo(1,2); // [1, 2] [1, 2] [1, 2] [1, 2]
可以看出,在不传入参数的情况下,call
和apply
的表现一致,都是改变this的指向,然后调用方法。
为什么arguments
可以转化成数组呢?
因为arguments
是一个类数组,由于js
是一种比较灵活的语言,所以可以对类数组进行操作。(!注意:对于非类数组的对象,是不可以使用此方法的。)
下面是传入参数1,打印arguments的结果
2),带参数
不带参数的
call
,apply
很容易理解,用法也很少,就是把类数组转换成就数组。接下来看一下带参数的用法,也是直接上代码。
//计算数组中的最大值
var a = [1,2,3,2,1];
Math.max.apply(null,a); // 9 由于没有对象调用Math.max方法,所以我们用null
Math.max.call(null,1,2,3,2,1); // 3
//合并数组
var b = [1,2];
var c = [3,4];
[].push.apply(b,c); // [1,2,3,4]
//[].push.apply(b,c)相当于
for(i = 0;i<c.length;i++) {
b.push(c[i]);
}
在有参数的情况下,apply相当于一个数组的遍历方法,它会对数组中的每一项进行操作,而call方法是将需要操作的变量以一个个的参数传进去。所以我们在需要操作数组中的每一项的时候用apply,参数比较少的时候用call。
为了方便记忆,你可以这样理解call
,apply
:
你使用一台手机,手机上有微信,微博,支付宝等软件,call和apply都是打开软件的操作,你打开他们,里面的个人信息就会指向你自己。