首頁 > 軟體

JS前端面試手寫apply和bind範例

2022-12-09 14:03:27

前言

面試官問:“聊一聊你理解的 applybind。”

於是我便開始開始介紹起這兩個知識點,最後順帶提了它們的實現程式碼。

這不提倒還好,一提就出了大事,一下子給面試官找到了面試題目。

面試官緊接著說:“既然你提到了程式碼,那就手寫一下它倆吧。”

我一下子不知所措。雖然我瞭解過 applybind 手寫程式碼,但是現在讓我立馬手寫出來它們,實屬有些困難。

不過最後還是硬著頭皮寫了一下,但是結果不盡人意。

apply && bind

函數 applybind 在日常開發中經常會被用到,理解它們的作用以及邏輯至關重要。所以今天我們來探討一下它們的實現邏輯,並對它們進行手寫,來學會如何輕鬆手寫它們。

apply && bind 作用

知己知彼,方能百戰百勝。在進行手寫之前,我們先來簡單聊一下它們。 眾所周知,apply 和 bind 作用是改變函數的呼叫物件。很多人對這個不是很理解,什麼是函數的呼叫物件呢?其實簡單點理解就是改變函數的 this 物件指向。因為這時候 this 在函數就充當了一個呼叫的作用,而 apply 和 bind 就是有著改變 this 指向的作用。

apply 的其他作用,是改變物件的執行上下文,並且是立即執行的。 bind 也能改變物件的執行上下文。

相同點 VS 不同點

它們的相同點在於都可以改變 this 的指向,並且傳入的第一個引數都是繫結的 this,不同點在於 bind 返回的是一個改變了 this 指向的函數,便於稍後呼叫,而 apply 會立即呼叫。另外 apply 是一次性傳入引數,而 bind 可以分為多次傳入。

輕鬆手寫

有了理論基礎,我們可以開始手寫部分了。

手寫實現 apply

我們先來看 applyapply 手寫實現其實很簡單,大致思路如下:

首先用 typeof 來檢查呼叫 apply 的物件是否為函數,如果不是則丟擲錯誤。然後將函數作為傳入的 context 物件的一個屬性,並呼叫該函數。 最後呼叫之後通過 delete 刪除該屬性,避免對傳入物件造成汙染。context 代表上下文物件。

程式碼如下:

Function.prototype.apply = function (context, args) {
  if (typeof this !== 'function') {
    console.log('not a function')
  }
  const fn = Symbol()
  context[fn] = this
  context[fn](...args)
  delete context[fn]
}

這裡使用到了新的 Symbol 資料型別,主要是避免在把函數賦值給 context 物件的時候,因為屬性名衝突而覆蓋掉原有屬性。

手寫實現 bind

相比較與 apply 手寫,我個人覺得 bind 手寫會相對複雜一些。bind 手寫實現思路如下:

和之前一樣,首先判斷呼叫物件是否為函數,然後獲取其餘傳入引數值,並建立一個函數返回。最後根據呼叫方式,傳入不同的繫結值。

函數內部使用 apply 來繫結函數呼叫,需要判斷函數作為建構函式的情況,這個時候需要傳入當前函數的 thisapply 呼叫,其餘情況都傳入指定的上下文物件 context

程式碼如下:

Function.prototype.myBind = function(context) {
  if (typeof this !== "function") {
    console.log("Error");
  }
  let args = [...arguments].slice(1),
  fn = this;
  return function Fn() {
    return fn.apply(
      this instanceof Fn ? this : context,  
      args.concat(...arguments)
    );
  };
};

總結

關於它們的手寫就到這裡了,相信下次再面對同樣的問題時處理起來就能遊刃有餘了。這兩個手寫各有各的特點,我個人建議可以多寫寫 bind 的手寫,我覺得它會比 apply 出錯率更高。

雖然文章中是以手寫 apply 和 bind 為主,但是並不缺少 js 相關知識點,比如 this 指向問題,總之,js 很重要,既是基礎又是重點。

以上就是手寫apply和bind範例的輕鬆實現詳解的詳細內容,更多關於apply bind手寫範例的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com