1. 程式人生 > >call, apply, bind 區別

call, apply, bind 區別

#call, apply, bind 區別及模擬實現call apply bind

      三者都可以用來改變this的指向,但是在用法上略有不同

 首先說一下call和apply的區別

  call和apply都是第一個引數是this的指向  ,只是傳參的方式不同

  call是 第二個以及第三依次類推都是當前函式的引數,每個引數用逗號相隔開

  而apply則是將所有的引數以陣列的形式來傳遞的

 call(window,引數1,引數1,引數3)

call和apply與bind的區別

call和apply相當於立即執行函式,使用時直接呼叫,而bind則類似於函式,使用時需要加()呼叫

同時bind傳參方式與call相同,引數都是一個一個傳遞的

模擬實現call  

程式碼

Function.prototype.myCall = function (context) {
  var context = context || window
  // 給 context 新增一個屬性
  // getValue.call(a, 'yck', '24') => a.fn = getValue
  context.fn = this
// 將 context 後面的引數取出來 var args = [...arguments].slice(1) // getValue.call(a, 'yck', '24') => a.fn('yck', '24') var result = context.fn(...args) // 刪除 fn delete context.fn return result }

模擬實現apply   方式與call相似只是傳參方式不同

 程式碼

Function.prototype.myApply = function (context) {
  
var context = context || window context.fn = this var result // 需要判斷是否儲存第二個引數 // 如果存在,就將第二個引數展開 if (arguments[1]) { result = context.fn(...arguments[1]) } else { result = context.fn() } delete context.fn return result }

模擬實現bind

程式碼

Function.prototype.myBind = function (context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  var _this = this
  var args = [...arguments].slice(1)
  // 返回一個函式
  return function F() {
    // 因為返回了一個函式,我們可以 new F(),所以需要判斷
    if (this instanceof F) {
      return new _this(...args, ...arguments)
    }
    return _this.apply(context, args.concat(...arguments))
  }
}