apply和call的用法(补充)
之前我写过一次apply和call的用法,这次我会更详细的总结一下。
1.apply和call的用法定义
在犀牛书的第六版的8.7.3章节有对apply和call的定义,但是理解起来有些绕,也有一部分翻译的原因。我还是觉得比较好理解的说法是:apply和call用来劫持其他对象的方法(或方法)归自己(新对象)所有。举个不恰当的例子,就是你有自行车我没有,所以我劫持你的骑一下。
对于里面的参数,两者第一个参数都是主动劫持的对象,比如f.call(o,1,2),就是要以对象o的方法的形式调用函数f(),对于后面的参数,apply会把这些参数放入到一个数组里面。
2.apply和call的用法例子
1)用于类的继承
js在模拟类的写法中,对于继承的功能实现可以用到call/apply, 详见类的封装和继承最佳方法和解析
这里面的Person.call(this,name,age,job);也可以写成 Person.apply(this,arguments);用arguments代替。另外我们发现方法并没有用到call,还是因为共享的原因,使用了//子类的原型去继承父类的实例:Sub.prototype = new Person();
2)js逻辑模块化的需要
这一块详见apply和call的用法
3)利用Apply的参数数组化来简化写法
//例子1
Math.max(3,6,9,1); //print 9
//如果我们定义一个数组
var array1 = [3,6,9,1];
Math.max(array1); //print NaN
//这样是不行的,可以自定义函数用循环比较的方式但是比较麻烦
function getMax(arr){
var arrLen=arr.length;
for(var i=0,ret=arr[0]; i小于111; i++){
ret=Math.max(ret,arr[i]);
}
return ret;
}
//如果想到apply实现就会很优雅
var array1 = [3,6,9,1];
Math.max.apply(Math,array1); //print 9
//例子2
var arr1=[1,3,4];
var arr2=[3,4,5];
//要求把arr2放到arr1后面,使得arr1成为[1,3,4,3,4,5];
//可以用concat,但是arr1并没有改变
arr1.concat(arr2) //print [1, 3, 4, 3, 4, 5]
arr1 //print [1, 3, 4]
//也可以用apply优雅实现
Array.prototype.push.apply(arr1,arr2) // print 6
arr1 // print [1, 3, 4, 3, 4, 5]