call,apply 都屬于 Function.prototype 的一個方法,它是 JavaScript 引擎內(nèi)在實現(xiàn)的,因為屬于 Function.prototype,所以每個 Function 對象實例(就是每個方法)都有 call,apply 屬性。
它們的作用都是重新定義函數(shù)的執(zhí)行環(huán)境,即 this 的指向。也就是把Function(即this)綁定到obj,這時候obj具備了Function的屬性和方法,說白一點就是obj繼承了Function的屬性和方法。
區(qū)別在于兩者的使用方式有差異:
var func=function(a,b,c){
alert([a,b,c])// [1 , 2 , 3]
}
func.call(null,1,2,3) //注意觀察參數(shù)
func.apply(null,[1,2,3]) //注意觀察參數(shù)
call函數(shù)第一個參數(shù)指定了函數(shù)體內(nèi)部的this對象的指向。然后傳參的時候是把每個參數(shù)傳進去,從第二個參數(shù)開始,每一個參數(shù)會依次的傳入函數(shù)中。
apply函數(shù) 第一個參數(shù)同樣指定函數(shù)體內(nèi)部的this對象的指向。然后把參數(shù)作為一個數(shù)組傳進去。
當我們使用call和apply的時候,如果我們第一個傳入的參數(shù)是null,函數(shù)體的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
- ‘借用構(gòu)造函數(shù)’,實現(xiàn)類似繼承的效果
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就實現(xiàn)了繼承。
- 小tips
//求傳入?yún)?shù)的最大值
Math.max(1,2,3); //3
如果想求一個數(shù)組中數(shù)字的最大值
let myArray = [1,2,3];
Math.max.apply(null, myArray);