欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS前端面試題詳解之手寫bind

 更新時間:2022年07月08日 08:55:31   作者:前端西瓜哥  
這篇文章主要為大家介紹了JavaScript前端面試題中常出現(xiàn)的問題:如何用JavaScript來實現(xiàn)內(nèi)置的bind方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下

大家好,我是前端西瓜哥,今天我們用 JS 來實現(xiàn)內(nèi)置的 bind 方法。

bind 的用法

在實現(xiàn)之前,我們先學(xué)習(xí)一下 Function.prototype.bind 的用法。

function.bind(thisArg[, arg1[, arg2[, ...]]])

bind 是函數(shù)特有的一個方法,可以創(chuàng)建一個綁定了 this 的新函數(shù)。

接受的參數(shù)為如下。

  • 第 1 個參數(shù) thisArg:用于修改 this 指向,且 this 一旦修改后將無法再改變。
  • arg1, arg2, ...:剩余的是可選的參數(shù)項,會在 bind 返回的新函數(shù)調(diào)用時,會作為函數(shù)的前幾個參數(shù)去調(diào)用。

this 的指向問題

我們在開發(fā)的時候,有時候會遇到 JS 的 this 指向丟失問題。

下面我們看一個例子。

const person = {
  nickname: '前端西瓜哥',
  eatWatermelon() {
    console.log(this.nickname + ' 吃西瓜');
  }
};

person.eatWatermelon();

上面的代碼中,在調(diào)用 person.eatWatermelon 時,this 指向 person,輸入結(jié)果為 前端西瓜哥 吃西瓜。

下面我們再執(zhí)行下面代碼。

const eatWatermelon = person.eatWatermelon;
eatWatermelon();

輸入結(jié)果就匪夷所思了起來,它是:undefined 吃西瓜

這是因為 this 的指向變成了 eatWatermelon() 執(zhí)行時所在作用域的 this,在瀏覽器 script 標(biāo)簽最外層時,是全局對象 window(嚴(yán)格模式下,全局對象 this 會變成 undefined)。

所以  eatWatermelon()  執(zhí)行中的 this.nickname 等價于 window.nickname,因為我們沒有賦值過,所以是 undefined。

有時候我們不希望 this 丟失,該怎么辦?

這時候我們就要用到一個 bind 方法,可以永久改變 this 的指向,且不能再改變。

const eatWatermelon = person.eatWatermelon.bind(person);
eatWatermelon();

這樣的話,eatWatermelon 函數(shù)的 this 就會永遠(yuǎn)指向 person,能輸出我們預(yù)期的 前端西瓜哥 吃西瓜。

所以,對于一個函數(shù)來說,它的 this 指向是在執(zhí)行時確定的

  • 如果函數(shù)是 bind 返回的,this 永遠(yuǎn)指向執(zhí)行 bind 綁定的那個 thisArg 值;
  • 如果函數(shù)前面有個對象,那 this 指向這個對象;
  • 如果函數(shù)前沒有對象,那 this 指向當(dāng)前的作用域(可能是函數(shù)作用域,可能是全局作用域)。

另一種控制 this 指向的寫法是使用 箭頭函數(shù),尤其適合在函數(shù)中調(diào)用另一個函數(shù)的情況,因為篇幅原因這里不展開講。

積累參數(shù)

bind 除了常用于強綁 this 外,另一個用的比較少的作用:預(yù)置函數(shù)參數(shù)。

function add(a, b, c) {
  return a + b + c;
}

const addSix = add.bind(null, 6);
const addSixThenAddFour = addSix.bind(null, 4);
addSixThenAddFour(5)
// 15

addSixThenAddFour(7)
// 17

實現(xiàn)一個 bind

下面進(jìn)入正題,實現(xiàn)一個 bind。

Function.prototype.myBind = function(thisArg, ...prefixArgs) {
  const fn = this;
  return function(...args) {
    return fn.call(thisArg, ...prefixArgs, ...args);
  }
}

要點是利用 閉包。

讓返回的新函數(shù)可以訪問到三個私有屬性:

  • fn(原來的函數(shù))
  • thisArg(需要強綁不變的 this 指向)
  • prefixArgs 屬性

當(dāng)我們調(diào)用這個新函數(shù)時,我們會執(zhí)行 fn 函數(shù),并利用 call 方法來指定 this 為 thisArg,然后將預(yù)填充的多個參數(shù),和新函數(shù)接收的參數(shù)依次填入。

最后不要忘記返回調(diào)用后的值。因為新函數(shù)是原函數(shù)的封裝,返回值也要和原函數(shù)表現(xiàn)一致。

結(jié)尾

bind 方法的實現(xiàn)并不復(fù)雜,更重要的是你要先掌握好 bind 的用法。

就好比做業(yè)務(wù)需求一樣,不明確需求,就容易產(chǎn)生 bug,

然后需要你對閉包有一定的認(rèn)識,知道如何去保存私有變量,以及封裝函數(shù)的寫法(記得 return 原函數(shù)的返回值)。

到此這篇關(guān)于JS前端面試題詳解之手寫bind的文章就介紹到這了,更多相關(guān)JS手寫bind內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論