91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用JS簡單實現apply、call和bind方法

發布時間:2022-02-21 09:11:05 來源:億速云 閱讀:155 作者:iii 欄目:開發技術

這篇文章主要講解了“如何使用JS簡單實現apply、call和bind方法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何使用JS簡單實現apply、call和bind方法”吧!

1.方法介紹

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

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

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

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

使用效果:

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

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

如何使用JS簡單實現apply、call和bind方法

call方法:使用一個指定的 this值和單獨給出的一個或多個參數來調用一個函數。

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

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

使用效果:

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

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

如何使用JS簡單實現apply、call和bind方法

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

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

thisArg:調用func函數時作為this參數傳遞給目標函數的值;arg1, arg2, ...:當目標函數被調用時,被預置入func函數的參數列表中的參數;

使用效果:

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

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

如何使用JS簡單實現apply、call和bind方法

總結:

apply和call主要用于在函數調用時給函數的this綁定對應的值,兩者作用類似,主要區別就是除了第一個參數,apply方法接受的是一個參數數組,而call方法接受的是參數列表。

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

2.apply、call和bind方法的實現

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

2.1.apply的實現

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

  // 2.對傳入的thisArg進行邊界判斷
  if (thisArg === null || thisArg === undefined) {
    // 當傳入的是null或者undefined是,被執行函數的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.調用獲取的fn函數,并將對應傳入的數組展開傳遞過去
  const result = thisArg[fnSymbol](...argArray)
  // 調用完后刪除添加的屬性
  delete thisArg[fnSymbol]

  // 6.將結果返回
  return result
}

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

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

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

如何使用JS簡單實現apply、call和bind方法

2.2.call的實現

call方法的實現和apply方法的實現差不多,主要在于后面參數的處理。

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

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

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

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

  // 5.將結果返回
  return result
}

測試:

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

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

如何使用JS簡單實現apply、call和bind方法

2.3.bind的實現

bind方法的實現稍微復雜一點,需要考慮到參數合并的問題。

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

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

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

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

    // 4.4.將結果返回
    return result
  }

  // 6.將新函數返回
  return newFn
}

測試:

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

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

如何使用JS簡單實現apply、call和bind方法

感謝各位的閱讀,以上就是“如何使用JS簡單實現apply、call和bind方法”的內容了,經過本文的學習后,相信大家對如何使用JS簡單實現apply、call和bind方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

张家界市| 保定市| 曲周县| 梁山县| 桦甸市| 济源市| 湖南省| 合阳县| 乐至县| 莒南县| 太原市| 荔浦县| 东丰县| 诸城市| 达尔| 林州市| 济源市| 丰都县| 佳木斯市| 自治县| 乾安县| 台湾省| 佛学| 阳泉市| 洮南市| 社旗县| 赣榆县| 柳河县| 黔西| 新民市| 汤原县| 鄂伦春自治旗| 滦南县| 丁青县| 瓦房店市| 昌吉市| 曲松县| 贵南县| 肇东市| 灵川县| 西和县|