bind、apply與call三者區(qū)別

在JS中,這三者都是用來改變函數(shù)的this對(duì)象的指向的,他們有什么樣的區(qū)別呢。

在說區(qū)別之前還是先總結(jié)一下三者的相似之處:

  1. 都是用來改變函數(shù)的this對(duì)象的指向的。
  2. 第一個(gè)參數(shù)都是this要指向的對(duì)象。
  3. 都可以利用后續(xù)參數(shù)傳參。

那么他們的區(qū)別在哪里的,先看一個(gè)例子。

 var xw = {
        name : "小王",
        gender : "男",
        age : 24,
        say : function() {
              alert(this.name + " , " + this.gender + " ,今年" + this.age);
        }
    }
var xh = {
        name : "小紅",
        gender : "女",
        age : 18
    }
xw.say();

那么如何用xw的say方法來顯示xh的數(shù)據(jù)呢。

對(duì)于call可以這樣:

xw.say.call(xh);

對(duì)于apply可以這樣:

xw.say.apply(xh);

而對(duì)于bind來說需要這樣:

xw.say.bind(xh)();

總之:bind與apply、call最大的區(qū)別就是:bind不會(huì)立即調(diào)用,其他兩個(gè)會(huì)立即調(diào)用,apply與call的區(qū)別是apply第二個(gè)是參數(shù)組,但是在確定的參數(shù)下,還是最好用call,call的效果會(huì)更高,但是在函數(shù)的延展性上使用apply更好

手寫一個(gè)call方法

考慮兩點(diǎn)

第一個(gè)參數(shù)為undefined或null的時(shí)候,那么會(huì)轉(zhuǎn)變?yōu)閣indow

改變了this執(zhí)行,讓新的對(duì)象可以執(zhí)行該函數(shù)。

Function.prototype.myCall = function(context) {
  // 判斷是否是undefined和null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  context.fn = this
  let args = [...arguments].slice(1)
  let result = context.fn(...args)
  delete context.fn
  return result
}

apply的實(shí)現(xiàn)

Function.prototype.myApply = function(context) {
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  context.fn = this
  let args = arguments[1]
  let result
  if (args) {
    result = context.fn(...args)
  } else {
    result = context.fn()
  }
  delete context.fn
  return result
}

bind實(shí)現(xiàn)

這里需要注意下,因?yàn)閎ind轉(zhuǎn)換后的函數(shù)可以作為構(gòu)造函數(shù)使用,此時(shí)this應(yīng)該指向構(gòu)造出的實(shí)例,而bind函數(shù)綁定的第一個(gè)參數(shù)。

Function.prototype.myBind = function(context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  let _this = this
  let args = [...arguments].slice(1)
  return function F() {
    // 判斷是否被當(dāng)做構(gòu)造函數(shù)使用
    if (this instanceof F) {
      return _this.apply(this, args.concat([...arguments]))
    }
    return _this.apply(context, args.concat([...arguments]))
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容