手寫JS函式的call、apply、bind

hello_world_1024發表於2023-02-14

之所以要寫這篇,是因為曾經面試被要求在白紙上手寫bind實現

  結果跟程式碼一樣清晰明確,一陣懵逼,沒寫出來!

  下面,擼起袖子就是幹!~

  把call、apply、bind一條龍都整一遍!~~

call

定義與使用

Function.prototype.call(): developer.mozilla.org/zh-CN/docs/…
// Function.prototype.call()樣例
function fun(arg1, arg2) {
  console.log(this.name)
  console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 接受的是一個引數列表;方法立即執行
fun.call(_this, 1, 2)
// 輸出:
YIYING
3

手寫實現

/** * 自定義call實現 * @param context   上下文this物件 * @param args      動態引數 */
Function.prototype.ownCall = function(context, ...args) {
  context = (typeof context === 'object' ? context : window)
  // 防止覆蓋掉原有屬性
  const key = Symbol()
  // 這裡的this為需要執行的方法
  context[key] = this
  // 方法執行
  const result = context[key](...args)
  delete context[key]
  return result
}
// 驗證樣例
function fun(arg1, arg2) {
  console.log(this.name)
  console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 接受的是一個引數列表;方法立即執行
fun.ownCall(_this, 1, 2)
// 輸出:
YIYING
3

apply

定義與使用

Function.prototype.apply(): developer.mozilla.org/zh-CN/docs/…
// Function.prototype.apply()樣例
function fun(arg1, arg2) {
  console.log(this.name)
  console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 引數為陣列;方法立即執行
fun.apply(_this, [1, 2])
// 輸出:
YIYING
3

手寫實現

/** * 自定義Apply實現 * @param context   上下文this物件 * @param args      引數陣列 */
Function.prototype.ownApply = function(context, args) {
  context = (typeof context === 'object' ? context : window)
  // 防止覆蓋掉原有屬性
  const key = Symbol()
  // 這裡的this為需要執行的方法
  context[key] = this
  // 方法執行
  const result = context[key](...args)
  delete context[key]
  return result
}
// 驗證樣例
function fun(arg1, arg2) {
  console.log(this.name)
  console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 引數為陣列;方法立即執行
fun.ownApply(_this, [1, 2])
// 輸出:
YIYING
3

bind

定義與使用

Function.prototype.bind()
: developer.mozilla.org/zh-CN/docs/…
// Function.prototype.bind()樣例
function fun(arg1, arg2) {
  console.log(this.name)
  console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 只變更fun中的this指向,返回新function物件
const newFun = fun.bind(_this)
newFun(1, 2)
// 輸出:
YIYING
3

參考 前端進階面試題詳細解答

手寫實現

/** * 自定義bind實現 * @param context     上下文 * @returns {Function} */
Function.prototype.ownBind = function(context) {
  context = (typeof context === 'object' ? context : window)
  return (...args)=>{
    this.call(context, ...args)
  }
}
// 驗證樣例
function fun(arg1, arg2) {
  console.log(this.name)
  console.log(arg1 + arg2)
}
const _this = { name: 'YIYING' }
// 只變更fun中的this指向,返回新function物件
const newFun = fun.ownBind(_this)
newFun(1, 2)
// 輸出:
YIYING
3

相關文章