天天看點

call、apply、bind的差別及使用文法三個文法相同點Object參數示例講解不同點apply示例用途

文法

函數.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

      var bindfn = fn.bind(1,8,9,10)
                 
      在控制台列印bindfn ,控制台運作結果如下:
      ƒ (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 {1}
      8
      9
      10
                 
      從結果看出,輸出的值并非是Number {2} 5 7 6,而是執行fn.bind(1,8,9,10) 代碼時傳進的參數,由此驗證了:【執行完bind函數,傳回的是綁定this以及參數的被執行函數】,即使以不同的參數再次調用該傳回函數bindfn,執行結果也不會改變。

apply示例用途

  1. 求數組[3,5,7,1,6]中的最大值:

    我們知道執行

    Math.max(3,5,7,1,6)
               
    執行完得到最大值7。但現在要傳入數組,則使用apply得到最大值
    Math.max.apply(null,[3,5,7,1,6] )
               
  2. 類的繼承:使用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 {name: "dog name"}
    dog name
               
    由此看出Dog類繼承了Animal類的屬性以及方法。

繼續閱讀