javascript函數方法:call、apply和bind

前言

最近在讀《javascript高級程序設計》疏通經脈,經過寫文的方式增強本身理解。javascript

函數方法

在前端面試的問題中少不了this指向的問題,而如下三種方法均可以改變this指向:前端

  1. apply()
  2. call()
  3. bind()

1. apply方法

apply()call()兩個方法的用途都是在特定的做用域中調用函數,實際上等於設置函數體內的this對象的值apply()方法接受兩個參數:java

  • 第一個參數:thisArg

thisArg該參數可選填,在 func 函數運行時使用的 this 值。若是這個函數處於非嚴格模式下,則指定爲nullundefined 時會自動替換爲指向全局對象,原始值會被包裝。若是該參數缺失時則指向全局對象面試

  • 第二個參數: argsArray

argsArray該參數可選填,接受一個數組或arguments(arguments知識傳送門:javascript:函數屬性梳理)。若是不填寫則表明不須要傳參。數組

let o1 = {
    number: 100
  }
  let o2 = {
    number: 200
  }
  function sum (num1, num2) {
    console.log(num1 + num2 + this.number)
  }
  sum.apply(o1, [1, 10]) //    111    將this指向o1
  sum.apply(o2, [1, 10]) //    211    將this指向o2
複製代碼

apply()不只能傳參,最重要的是能夠改變函數賴以運行的做用域!!!在上面的例子中,當傳入o1時,this.number指向了o1裏的number;當傳入o2時,this.number指向了o2裏的number瀏覽器

2. call方法

理解了apply(),那理解call()便不費吹灰之力。由於call()apply()方法惟一的區別在於第二個參 接受參數的形式不一樣做用徹底相同。call()傳遞給函數的參數只能逐個列舉出來,看下面的例子:bash

function sum (num1, num2) {
    console.log(num1 + num2)
  }
  sum.call(o1, 1, 10)  //  11
複製代碼

3. bind方法

bind()方法建立一個新的函數,在調用時設置this關鍵字爲提供的值。並在調用新函數時,將給定參數列表做爲原函數的參數序列的前若干項。和call()apply()的區別在於:bind()會建立一個原函數的拷貝(綁定函數),擁有指定的this值和初始參數,並返回這個函數。看下MDN裏的描述:app

bind() 最簡單的用法是建立一個函數,不論怎麼調用,這個函數都有一樣的 this 值。JavaScript新手常常犯的一個錯誤是將一個方法從對象中拿出來,而後再調用,指望方法中的 this 是原來的對象(好比在回調中傳入這個方法)。若是不作特殊處理的話,通常會丟失原來的對象。基於這個函數,用原始的對象建立一個綁定函數,巧妙地解決了這個問題:函數

this.x = 9;    // 在瀏覽器中,this指向全局的 "window" 對象
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
retrieveX();   
// 返回9 - 由於函數是在全局做用域中調用的

// 建立一個新函數,把 'this' 綁定到 module 對象
// 新手可能會將全局變量 x 與 module 的屬性 x 混淆
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
複製代碼

結語

關於call、apply和bind函數的做用極其類似,但有不一樣之處,關於如何更好運用還得在探索。post

參考資料:

  • 《javascript高級程序設計》
  • MDN--bind

種一棵樹最好的時間是十年前。

相關文章
相關標籤/搜索