call和apply的區別
介紹:
每個函數都包含兩個非繼承而來的方法:call()
和apply()
;
call與apply都屬於Function.prototype的一個方法,所以每個function實例都有call、apply屬性;
1.相同點:改變this的指向。
2.區別:傳值的方式不一樣。
call(obj,arg1,arg2,arg3) 通過調用call 方法,在傳第一個參數的時候,函數裏的this指向第一個參數。從第二參數起依次傳入給函數的參數值。
apply(obj,args)調用 apply方法,第一個參數同call一樣,是函數裏this指向第一個參數,第二個參數爲數組。此方法會遍歷傳入參數的值。
Call實現方法:
過程思考:1.首先是所有的函數都可以調用call,說明call是函數原型上的方法,所有實例都可以調用,即function.prototype.call.
1.1:在call方法裏獲取調用call()函數。
1.2如果第一個參數沒有傳入,那麼默認指向window/global
1.3傳入的call的第一個參數是this指向的對象,根據隱式綁定的規則。我們知道obj.foo(),foo()中的this指向obj;因此我們可以obj.func(...args)
1.4執行返回結果。
上代碼:
Function.prototype.call = function(){
let [thisArg,...args]=[...arguments];
if(!thisArg){
thisArg = typeof window === 'undefined' ? global : window;
}
thisArg.func = this;
let result = thisArg.func(...args);
delete thisArg.func;
return result;
}
apply的實現方法:
Function.prototype.apply = function(thisArg,rest){
let result;
if(!thisArg){
thisArg= typeof window === 'undefined'? global:window;
}
thisArg.func = this;
if(!rest){
result = thisArg.func();
}else{
result = thisArg.func(...rest);
}
delete thisArg.func;
return result;
}
* 參考公衆號前端宇宙 (這兒有20道大廠面試題等你查收)