文法
函數.apply(Object對象,[數組])
函數.call(Object,a1,a2,a3…)
函數.bind(Object,a1,a2,a3…)
三個文法相同點
call、apply、bind都是被一個函數調用;
Object參數:改變該函數的this對象
除Object參數外的其他參數(數組或者a1…):該函數所需要的參數
Object參數示例講解
定義一個fn函數
var fn= function(a,b,c){
console.log(this);
console.log(a);
console.log(b);
console.log(c);
}
如果直接調用函數fn(1,2,3),控制台運作結果如下:
Window {}
1
2
3
如果調用函數fn.apply(1,[2,7,9]); ,控制台運作結果如下:
Number {1}
2
7
9
經過上述兩次調用結果的比較,你會發現console.log(this)代碼輸出的this值改變了,由window對象變成了Number對象,是以驗證了Object參數是改變被執行函數的this對象 (call、bind方法中參數Object也是同樣的作用)
不同點
-
函數.apply(Object對象,[數組])
apply第二個參數必須是一個數組,當傳入函數時,會被擴充成多個參數。 擴充:類似與ES6文法中的…arr
比如上述執行函數 fn.apply(1,[2,7,9]),數組[2,7,9]就會擴充成多個參數2,7,9分别指派給fn(a,b,c)方法中的a,b,c
-
函數.call(Object對象, a1,a2,a3)
相比apply,a1,a2,a3不可傳數組進行擴充
-
函數.bind(Object,a1,a2,a3…)
執行完bind函數,傳回的是綁定this以及參數的被執行函數
-
示例講解
在控制台上執行bind函數且将結果指派給bindfn
在控制台列印bindfn ,控制台運作結果如下:var bindfn = fn.bind(1,8,9,10)
ƒ (a,b,c){ console.log(this); console.log(a); console.log(b); console.log(c); }
從結果可看到:執行完bind函數,傳回的是一個和fn一樣的函數。
然後再在控制台執行bind函數傳回的函數bindfn如下代碼:
控制台運作結果為:bindfn(2,5,7,6)
從結果看出,輸出的值并非是Number {2} 5 7 6,而是執行fn.bind(1,8,9,10) 代碼時傳進的參數,由此驗證了:【執行完bind函數,傳回的是綁定this以及參數的被執行函數】,即使以不同的參數再次調用該傳回函數bindfn,執行結果也不會改變。Number {1} 8 9 10
-
apply示例用途
-
求數組[3,5,7,1,6]中的最大值:
我們知道執行
執行完得到最大值7。但現在要傳入數組,則使用apply得到最大值Math.max(3,5,7,1,6)
Math.max.apply(null,[3,5,7,1,6] )
-
類的繼承:使用apply可以實作類的繼承,如下所示
現建立Animal類、Dog類,Dog類繼承Animal類
var Animal = function(name){ this.name = name; console.log(this); console.log(this.name); } var Dog = function(name,color){ Animal.apply(this,arguments); }
注:Animal.apply(this,arguments);此句代碼中,
this指代Dog類,
arguments數組是所有(非箭頭)函數中都可用的局部變量,代表傳入的參數集合
然後我們建立一個dog對象 【注:此時的arguments為: Arguments(2) [“dog name”, “orange”]】
控制台運作結果如下:var dog1 = new Dog("dog name",'orange');
由此看出Dog類繼承了Animal類的屬性以及方法。Dog {name: "dog name"} dog name