手動實現bind、call、apply方法

轉載請註明出處

bind()

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

語法:
function.bind(thisArg[,arg1[,arg2[, ...]]])
示例:
var module = {
  x: 42,
  getX: function() {
    return this.x;
  }
}

var unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// expected output: undefined

var boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// expected output: 42
以下是對 bind() 的一個實現:
Function.prototype.bind = function(context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  let _this = this
  let args = [...arguments].slice(1)
  return function F() {
    // 判斷是否被當做構造函數使用
    if (this instanceof F) {
      return _this.apply(this, args.concat([...arguments]))
    }
    return _this.apply(context, args.concat([...arguments]))
  }
}

apply()

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

語法:
func.apply(thisArg, [argsArray])
示例:
var numbers = [5, 6, 2, 3, 7];

var max = Math.max.apply(null, numbers);

console.log(max);
// expected output: 7

var min = Math.min.apply(null, numbers);

console.log(min);
// expected output: 2
以下是對apply() 的一個實現:
Function.prototype.apply = function(context) {
  // context就是apply的第一個參數,在這裏也就是obj
  // 判斷是否是undefined和null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  // this也就是調用apply的函數 把函數賦值給context下面的一個鍵,這裏是fn
  context.fn = this
  // arguments就是傳進來的參數
  let args = arguments[1]
  let result
  if (args) {
      result = context.fn(...args)
  } else {
      result = context.fn()
  }
  delete context.fn
  return result
}
let test = function (sex) {
    console.log(this.name + sex)
}
let obj = {
    name: '我是'
}
test.apply(obj, ['test'])

call()

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

語法:
fun.call(thisArg, arg1, arg2, ...)
示例:
function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

console.log(new Food('cheese', 5).name);
// expected output: "cheese"
以下是對 call() 的一個實現:
Function.prototype.call = function(context) {
  // context就是call的第一個參數,在這裏也就是obj
  // 判斷是否是undefined和null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  // this也就是調用call的函數 把函數賦值給context下面的一個鍵,這裏是fn
  context.fn = this
  // arguments就是傳進來的參數
  let args = [...arguments].slice(1)
  let result = context.fn(...args)
  delete context.fn
  return result
}
let test = function (sex) {
    console.log(this.name + sex)
}
let obj = {
    name: '我是'
}
test.call(obj, 'test')

參考資料


歡迎瀏覽我的個人網站
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章