學習 apply 和 call

Function.prototype.apply() & Function.prototype.call()

官方描述

  1. apply() 方法在指定 this 值和參數(參數以數組或類數組對象的形式存在)的狀況下調用某個函數。fun.apply(thisArg[, argsArray])javascript

  2. call() 方法在使用一個指定的this值和若干個指定的參數值的前提下調用某個函數或方法。fun.call(thisArg[, arg1[, arg2[, ...]]])java

  3. 二者基本一致,只有一個區別,就是call()方法接受的是若干個參數的列表,而apply()方法接受的是一個包含多個參數的數組。segmentfault

注意點
thisArg: 在 fun 函數運行時指定的 this 值。須要注意的是,指定的 this 值並不必定是該函數執行時真正的 this 值,若是這個函數處於非嚴格模式下,則指定爲 nullundefined 時會自動指向全局對象(瀏覽器中就是window對象,說明thisArg能夠不傳),同時值爲原始值(數字,字符串,布爾值)的 this 會指向該原始值的自動包裝對象(Number,String,Boolean)。數組

溫故

call爲例,apply把後面參數轉化成數組格式便可瀏覽器

  1. 在調用一個存在的函數時,爲其指定一個全新的 this 對象(原函數的this對象這次調用被覆蓋),而且能夠傳遞參數,app

    function test(a) {
        console.log(this.one);
        console.log(a)
    }
    test.call({one:1},2)
    //  1
    //  2
    //咱們在test函數執行的時候綁定一個對象 {one:1} 和參數 2
  2. 調用父構造函數,實現繼承函數

    function a(a) {
        this.a = a
    }
    function b(b) {
        this.b = b
    }
    //想要建立一個實例對象擁有a和b裏面的屬性
    function c(a,b){
        //至關於a,b函數執行了一次,因此屬性會被建立
        a.call(this,a)
        b.call(this,b)
    }
    //效果等同於
    function c(a,b){
        this.a = a;
        this.b = b
    }
    var d = new c(1,2);
    d會同時用於a,b的屬性,這樣在涉及到不少屬性繼承時候就很方便
    //c {a: 1, b: 1}
  3. 使用call方法調用匿名函數,引用官方示例,其實和1相似this

var animals = [
      {species: 'Lion', name: 'King'},
      {species: 'Whale', name: 'Fail'}
    ];
    
    for (var i = 0; i < animals.length; i++) {
      (function (i) { 
        this.print = function () { 
          console.log('#' + i  + ' ' + this.species + ': ' + this.name); 
        } 
        this.print();
      }).call(animals[i], i);
    }
    // #0 Lion: King
    // #1 Whale: Fail

知新(for me)

因爲call方法須要窮舉全部須要傳遞的參數,因此只能在已知參數的狀況下使用,apply則零活不少,可是接收參數的狀況是同樣的,apply能夠將數組形式默認轉化成一個參數列表 參數[a,b,c]會以(a,b,c)的形式接收。
舉例來講:prototype

//比較一組數據大小
 Math.max(9,2,4,6,7) // 9
 Math.max([9,2,4,6,7]) // NaN
//由於Math.max 方法不能接收一個數組 ,因此咱們能夠進行遍歷
var arr = [9,2,4,6,7],arr_len = arr.length,maxNumber = arr[0];
for(var i = 1 ;i< arr_len ;i++){
maxNumber = Math.max(maxNumber,arr[i])
}
maxNumber // 9
//這樣可以達到效果,可是能夠有更方便高效的方法:用apply進行改造
 Math.max.apply(null,[9,2,4,6,7]) //9 
//通過apply轉化,Math.max這次執行的時候真正接收的參數是  (9,2,4,6,7)
//因此相似這種原本須要寫成遍歷數組變量的任務 ,均可以用apply執行,Array.prototype.push也是

還有個 bind方法和這兩個很相似,能夠參考另外一篇內容,詳細說了bind方法
javascript原生一步步實現bind分析code

以上是我的理解,若是有誤,感謝指導!

相關文章
相關標籤/搜索