前面的话
ECAMScript 3 给Function的原型定义两个方法。Function.prototype.call()与
Function.prototype.apply()方法。这两个方法尤为重要,熟练掌握这两个方法,
是真正成为前端程序员重要的一步。
●call()与apply()的定义
函数是也是对象,对象就有方法和属性,每个函数都可以使用call()与apply()方法。
Function.apply(obj,args);
obj: 这是一个对象,将代替Function里面的this对象
args:这是一个数组,它将作为参数传递给Function(args —> arguments)
call与apply()的区别只是参数列表不同,作用都是相同的。
Function.call(obj,value1,value2…)
obj: 这是一个对象,将代替Function里面的this对象
value1,value2…: 是参数列表
●call()与apply()的作用:改变this指向
当传入的是null时,this指向为window,传入其他的对象this则指向传入的对象
var obj1 = {
name: 'wan'
};
var obj2 = {
name: 'li'
};
window.name = 'yang';
function getName() {
console.log(this.name);
}
getName.call(null);// yang
getName.call(obj1);// wan
getName.call(obj2);// li
apply实例:
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name, age, sex, grad) {
Person.apply(this,arguments);
this.grad = grad;
}
var std = new Student('wan', 20, '女', 90);
console.log('name:'+ std.name + ' age:' + std.age + ' sex:' + std.sex + ' grad' + std.grad);
我们会发现结果std对象的name,age,sex我们都可以得到。就是因为apply()方法的作用,它改变了this的指向.
Person.apply()这条语句就一定会执行Person构造函数,而Student构造函数里面的this指向的是student这个对象,apply方法
里面传入了这个this,此时相当于Person构造函数里面的this被Student构造函数里面的this(student对象)所代替。
call()实例:
只需将上例的Person.apply(this,arguments)改为Person.call(this,name,age,sex)即可。
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name, age, sex, grad) {
Person.call(this,name,age,sex);
this.grad = grad;
}
var std = new Student('wan', 20, '女', 90);
console.log('name:'+ std.name + ' age:' + std.age + ' sex:' + std.sex + ' grad' + std.grad);
call()方法与apply()方法基本一样,就是参数列表不一样,apply(obj,args)传入的是一个数组,而call(obj,value1,value2…)方法 传入的是一个一个的值。
●apply()方法的一些妙用
上例:我们可以发现apply()的第二个参数是一个数组,而Person()构造函数里面的形参是一个一个的值。那么apply可以将一个数组 解析为一个一个的参数。利用这一特性,可以有以下高效方法。
1:Math.max()可以实现得到数组最大值
Math.max()的参数是不支持数组的,但是它支持Math.max(value1,value2…),利用apply()方法的特性可以实现。
Math.max.apply(null,[13, 45, 89, 90]);// 90
apply()方法将数组解析为一个一个参数出入Math.max()方法
2: Math.min()可以实现得到数组最小值
Math.min.apply(null,[13, 45, 89, 90]);// 13
3: Array.prototype.push可以将一个数组添加到另一个数组的尾部
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
console.log( Array.prototype.push.apply(arr1,arr2));
console.log(arr1);// [0,1,2,3,4,5] arr1向后面追加了arr2
●总结
掌握一个知识点就要多理解,多敲代码,多看看别人的总结。第三部分apply的妙用参考阮一峰老师的‘es6标准入门’这本书。