call,apply 都属于 Function.prototype 的一个方法,它是 JavaScript 引擎内在实现的,因为属于 Function.prototype,所以每个 Function 对象实例(就是每个方法)都有 call,apply 属性。
它们的作用都是重新定义函数的执行环境,即 this 的指向。也就是把Function(即this)绑定到obj,这时候obj具备了Function的属性和方法,说白一点就是obj继承了Function的属性和方法。
区别在于两者的使用方式有差异:
var func=function(a,b,c){
alert([a,b,c])// [1 , 2 , 3]
}
func.call(null,1,2,3) //注意观察参数
func.apply(null,[1,2,3]) //注意观察参数
call函数第一个参数指定了函数体内部的this对象的指向。然后传参的时候是把每个参数传进去,从第二个参数开始,每一个参数会依次的传入函数中。
apply函数 第一个参数同样指定函数体内部的this对象的指向。然后把参数作为一个数组传进去。
当我们使用call和apply的时候,如果我们第一个传入的参数是null,函数体的this会指向默认的宿主对象,在浏览器中就是window
call和apply的用途
- 改变this的指向
var obj1 = {name:'kim'}
var obj2 = {name :'john'}
window.name = 'window';
var getName = function () {
console.log(this.name);
}
getName ();//window
getName.call(obj1);// kim
getName.apply(obj2);//john
- ‘借用构造函数’,实现类似继承的效果
function Person (name,age){
this.name=name;
his.age=age;
}
var Student=function(name,age,gender){
Person.call(this,name,age);//this继承了person的属性和方法this.gender=gender;
}
var student=new Student("陈安东",20,"男");
alert("姓名:"+student.name+"\n"+"年龄:"+student.age+"\n"+"性别:"+student.gender);
这样call就实现了继承。
- 小tips
//求传入参数的最大值
Math.max(1,2,3); //3
如果想求一个数组中数字的最大值
let myArray = [1,2,3];
Math.max.apply(null, myArray);