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

使用JS簡單實現(xiàn)apply、call和bind方法的實例代碼

 更新時間:2022年02月20日 08:11:45   作者:MomentYY  
在JavaScript中,call、apply和bind是Function對象自帶的三個方法,這三個方法的主要作用是改變函數(shù)中的this指向,下面這篇文章主要給大家介紹了關(guān)于如何使用JS簡單實現(xiàn)apply、call和bind方法的相關(guān)資料,需要的朋友可以參考下

1.方法介紹

apply、call和bind都是系統(tǒng)提供給我們的內(nèi)置方法,每個函數(shù)都可以使用這三種方法,是因為apply、call和bind都實現(xiàn)在了Function的原型上(Function.prototype),而他們的作用都是給我們函數(shù)調(diào)用時顯式綁定上this。下面先介紹一下它們的基本用法:

apply方法:調(diào)用一個具有給定this值的函數(shù),以及以一個數(shù)組(或類數(shù)組對象)的形式提供的參數(shù)。

使用語法:func.apply(thisArg, [argsArray])

thisArg:在func函數(shù)調(diào)用時綁定的this值;[argsArray]:一個數(shù)組或者類數(shù)組對象,其中的數(shù)組元素將作為單獨的參數(shù)傳給func函數(shù);

使用效果:

function foo(x, y ,z) {
  console.log(this, x, y, z)
}

const obj = { name: 'curry', age: 30 }
/**
 * 1.將obj對象綁定給foo函數(shù)的this
 * 2.數(shù)組中的1 2 3分別傳遞給foo函數(shù)對應(yīng)的三個參數(shù)
 */
foo.apply(obj, [1, 2, 3])

call方法:使用一個指定的 this值和單獨給出的一個或多個參數(shù)來調(diào)用一個函數(shù)。

使用語法:func.call(thisArg, arg1, arg2, ...)

thisArg:在func函數(shù)調(diào)用時綁定的this值;arg1, arg2, ...:指定的參數(shù)列表,將作為參數(shù)傳遞給func函數(shù);

使用效果:

function foo(x, y ,z) {
  console.log(this, x, y, z)
}

const obj = { name: 'curry', age: 30 }
/**
 * 1.將obj對象綁定給foo函數(shù)的this
 * 2.call剩余參數(shù)中的a b c分別傳遞給foo函數(shù)對應(yīng)的三個參數(shù)
 */
foo.call(obj, 'a', 'b', 'c')

bind方法:創(chuàng)建一個新的函數(shù),在bind()被調(diào)用時,這個新函數(shù)的this被指定為bind()的第一個參數(shù),而其余參數(shù)將作為新函數(shù)的參數(shù),供調(diào)用時使用。

使用語法:func.bind(thisArg[, arg1[, arg2[, ...]]])

thisArg:調(diào)用func函數(shù)時作為this參數(shù)傳遞給目標函數(shù)的值;arg1, arg2, ...:當(dāng)目標函數(shù)被調(diào)用時,被預(yù)置入func函數(shù)的參數(shù)列表中的參數(shù);

使用效果:

function foo(...args) {
  console.log(this, ...args)
}

const obj = { name: 'curry', age: 30 }
/**
 * 1.將obj對象綁定給foo函數(shù)的this
 * 2.bind剩余參數(shù)中的1 2 3分別傳遞給foo函數(shù)中參數(shù)
 * 3.也可在newFoo調(diào)用時傳入?yún)?shù),這時bind傳遞的參數(shù)會與newFoo調(diào)用時傳遞的參數(shù)進行合并
 */
const newFoo = foo.bind(obj, 1, 2, 3)
newFoo()
newFoo('a', 'b', 'c')

總結(jié):

apply和call主要用于在函數(shù)調(diào)用時給函數(shù)的this綁定對應(yīng)的值,兩者作用類似,主要區(qū)別就是除了第一個參數(shù),apply方法接受的是一個參數(shù)數(shù)組,而call方法接受的是參數(shù)列表。

bind也是給函數(shù)指定this所綁定的值,不同于apply和call的是,它會返回一個新的函數(shù),新函數(shù)中的this指向就是我們所指定的值,且分別傳入的參數(shù)會進行合并。

2.apply、call和bind方法的實現(xiàn)

為了所有定義的函數(shù)能夠使用我們自定義的apply、call和bind方法,所以需要將自己實現(xiàn)的方法掛在Function的原型上,這樣所有的函數(shù)就可以通過原型鏈找到自定義的這三個方法了。

2.1.apply的實現(xiàn)

Function.prototype.myApply = function(thisArg, argArray) {
  // 1.獲取當(dāng)前需要被執(zhí)行的函數(shù)
  // 因為myApply是需要被當(dāng)前函數(shù)進行調(diào)用的,根據(jù)this的隱式綁定,此處的this就是指向當(dāng)前需要被執(zhí)行的函數(shù)
  const fn = this

  // 2.對傳入的thisArg進行邊界判斷
  if (thisArg === null || thisArg === undefined) {
    // 當(dāng)傳入的是null或者undefined是,被執(zhí)行函數(shù)的this直接指向全局window
    thisArg = window
  } else {
    // 將傳入的thisArg對象化,方便后面在thisArg添加屬性
    thisArg = Object(thisArg)
  }
  // 也可簡單寫成三元運算符:
  // thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg)

  // 3.將獲取的fn添加到thisArg對象上
  // 這里使用Symbol的原因是避免外部傳入的thisArg中的屬性與添加fn有沖突
  const fnSymbol = Symbol()
  Object.defineProperty(thisArg, fnSymbol, {
    enumerable: false,
    configurable: true,
    writable: false,
    value: fn
  })
  // 也可簡單寫成
  // thisArg[fnSymbol] = fn

  // 4.對argArray進行判斷
  // 看是否有傳入值,沒有值傳入就默認 []
  argArray = argArray || []

  // 5.調(diào)用獲取的fn函數(shù),并將對應(yīng)傳入的數(shù)組展開傳遞過去
  const result = thisArg[fnSymbol](...argArray)
  // 調(diào)用完后刪除添加的屬性
  delete thisArg[fnSymbol]

  // 6.將結(jié)果返回
  return result
}

測試:雖然打印出來的對象中還存在Symbol屬性,實際上已經(jīng)通過delete刪除了,這里是對象引用的問題。

function foo(x, y, z) {
  console.log(this, x, y, z)
}

foo.myApply({name: 'curry'}, [1, 2, 3])

2.2.call的實現(xiàn)

call方法的實現(xiàn)和apply方法的實現(xiàn)差不多,主要在于后面參數(shù)的處理。

Function.prototype.myCall = function(thisArg, ...args) {
  // 1.獲取當(dāng)前需要被執(zhí)行的函數(shù)
  const fn = this

  // 2.對傳入的thisArg進行邊界判斷
  thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg)

  // 3.將獲取的fn添加到thisArg對象上
  const fnSymbol = Symbol()
  thisArg[fnSymbol] = fn

  // 4.調(diào)用獲取的fn函數(shù),并將對應(yīng)傳入的args傳遞過去
  const result = thisArg[fnSymbol](...args)
  // 調(diào)用完后刪除添加的屬性
  delete thisArg[fnSymbol]

  // 5.將結(jié)果返回
  return result
}

測試:

function foo(x, y, z) {
  console.log(this, x, y, z)
}

foo.myCall({name: 'curry'}, 1, 2, 3)

2.3.bind的實現(xiàn)

bind方法的實現(xiàn)稍微復(fù)雜一點,需要考慮到參數(shù)合并的問題。

Function.prototype.myBind = function(thisArg, ...argsArray) {
  // 1.獲取當(dāng)前的目標函數(shù),也就是當(dāng)前使用myBind方法的函數(shù)
  const fn = this

  // 2.對傳入的thisArg進行邊界判斷
  thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg)

  // 3.將獲取的fn添加到thisArg對象上
  const fnSymbol = Symbol()
  thisArg[fnSymbol] = fn

  // 4.定義一個新的函數(shù)
  function newFn(...args) {
    // 4.1.合并myBind和newFn傳入的參數(shù)
    const allArgs = [...argsArray, ...args]
    // 4.2.調(diào)用真正需要被調(diào)用的函數(shù),并將合并后的參數(shù)傳遞過去
    const result = thisArg[fnSymbol](...allArgs)
    // 4.3.調(diào)用完后刪除添加的屬性
    delete thisArg[fnSymbol]

    // 4.4.將結(jié)果返回
    return result
  }

  // 6.將新函數(shù)返回
  return newFn
}

測試:

function foo(x, y, z) {
  console.log(this, x, y, z)
}

const newFoo = foo.myBind({ name: 'curry' }, 1, 2)
newFoo(3)

總結(jié)

到此這篇關(guān)于使用JS簡單實現(xiàn)apply、call和bind方法的文章就介紹到這了,更多相關(guān)JS實現(xiàn)apply、call和bind方法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解如何使用JavaScript實現(xiàn)自定義的雙向數(shù)據(jù)綁定

    詳解如何使用JavaScript實現(xiàn)自定義的雙向數(shù)據(jù)綁定

    雙向數(shù)據(jù)綁定是一種編程模式,用于在用戶界面和數(shù)據(jù)模型之間實現(xiàn)數(shù)據(jù)的同步更新,它允許用戶界面中的數(shù)據(jù)變化自動更新到數(shù)據(jù)模型中,在這篇文章中,我會使用基于觀察者模式和基于Proxy對象來實現(xiàn)JS的自定義雙向數(shù)據(jù)綁定
    2023-08-08
  • Javascript的無new構(gòu)建實例詳解

    Javascript的無new構(gòu)建實例詳解

    這篇文章主要介紹了Javascript的無new構(gòu)建實例詳解的相關(guān)資料,小編感覺介紹的非常詳細,具有參考借鑒價值,感興趣的朋友一起學(xué)習(xí)吧
    2016-05-05
  • 小程序?qū)崿F(xiàn)tab更換頁面效果

    小程序?qū)崿F(xiàn)tab更換頁面效果

    這篇文章主要為大家詳細介紹了小程序?qū)崿F(xiàn)tab更換頁面效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 微信小程序 彈窗自定義實例代碼

    微信小程序 彈窗自定義實例代碼

    這篇文章主要介紹了微信小程序 彈窗自定義實例代碼的相關(guān)資料,有時候做開發(fā)項目的時候需要根據(jù)客戶需求更改原系統(tǒng)的組件,這里就對小程序中彈窗進行更改,需要的朋友可以參考下
    2017-03-03
  • 關(guān)于base64編碼和解碼的js工具函數(shù)

    關(guān)于base64編碼和解碼的js工具函數(shù)

    這篇文章主要介紹了關(guān)于base64編碼和解碼的js工具函數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • GoJs中使用HTML方法示例

    GoJs中使用HTML方法示例

    這篇文章主要為大家介紹了GoJs中使用HTML方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • JavaScript Archive Network 集合

    JavaScript Archive Network 集合

    JavaScript Archive Network 集合...
    2007-05-05
  • Three.js中矩陣和向量的使用教程

    Three.js中矩陣和向量的使用教程

    這篇文章主要給大家介紹了關(guān)于Three.js中矩陣和向量使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Three.js具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 一起來學(xué)習(xí)JavaScript的BOM操作

    一起來學(xué)習(xí)JavaScript的BOM操作

    這篇文章主要為大家詳細介紹了JavaScript BOM操作,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • JavaScript+CSS實現(xiàn)的可折疊二級菜單實例

    JavaScript+CSS實現(xiàn)的可折疊二級菜單實例

    這篇文章主要介紹了JavaScript+CSS實現(xiàn)的可折疊二級菜單,以完整實例形式分析了JavaScript基于頁面元素節(jié)點及樣式的動態(tài)操作實現(xiàn)折疊菜單的相關(guān)技巧,需要的朋友可以參考下
    2016-02-02

最新評論