call,apply和bind

call,apply和bind

  • JavaScript 中 call()、apply()、bind() 的用法

轉(zhuǎn)載網(wǎng)址:https://www.runoob.com/w3cnote/js-call-apply-bind.html

先看明白下面:

例1
obj.objAge;  // 17
obj.myFun()  // 小張年齡 undefined

例2
shows()  // 盲僧 

比較一下這兩者 this 的差別,第一個(gè)打印里面的 this 指向 obj,第二個(gè)全局聲明的 shows() 函數(shù) this 是 window ;

1,call()、apply()、bind() 都是用來重定義 this 這個(gè)對(duì)象的!
obj.myFun.call(db);    // 德瑪年齡 99
obj.myFun.apply(db);    // 德瑪年齡 99
obj.myFun.bind(db)();   // 德瑪年齡 99

以上出了 bind 方法后面多了個(gè) () 外 ,結(jié)果返回都一致!
由此得出結(jié)論,bind 返回的是一個(gè)新的函數(shù),你必須調(diào)用它才會(huì)被執(zhí)行。

2,對(duì)比call 、bind 、 apply 傳參情況下
obj.myFun.call(db,'成都','上海');     // 德瑪 年齡 99  來自 成都去往上海
obj.myFun.apply(db,['成都','上海']);      // 德瑪 年齡 99  來自 成都去往上海  
obj.myFun.bind(db,'成都','上海')();       // 德瑪 年齡 99  來自 成都去往上海
obj.myFun.bind(db,['成都','上海'])();   // 德瑪 年齡 99  來自 成都, 上海去往 undefined

微妙的差距!
從上面四個(gè)結(jié)果不難看出:
call 、bind 、 apply 這三個(gè)函數(shù)的第一個(gè)參數(shù)都是 this 的指向?qū)ο?,第二個(gè)參數(shù)差別就來了:
call 的參數(shù)是直接放進(jìn)去的,第二第三第 n 個(gè)參數(shù)全都用逗號(hào)分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' )。
apply 的所有參數(shù)都必須放在一個(gè)數(shù)組里面?zhèn)鬟M(jìn)去 obj.myFun.apply(db,['成都', ..., 'string' ])。
bind 除了返回是函數(shù)以外,它 的參數(shù)和 call 一樣。
當(dāng)然,三者的參數(shù)不限定是 string 類型,允許是各種類型,包括函數(shù) 、 object 等等!

  • 說說bind、call、apply 區(qū)別?

1. call 和 apply 都是為了解決改變 this 的指向。作用都是相同的,只是傳參的方式不同。除了第一個(gè)參數(shù)外,call 可以接收一個(gè)參數(shù)列表,apply 只接受一個(gè)參數(shù)數(shù)組。
2. call和apply立即執(zhí)行并且返回值是你調(diào)用的方法的返回值,若該方法沒有返回值,則返回undefined。bind是改變this后返回一個(gè)新的函數(shù),他不會(huì)立即執(zhí)行。

  • 實(shí)現(xiàn)call、apply 、bind函數(shù)?

轉(zhuǎn)載網(wǎng)址:https://zhuanlan.zhihu.com/p/286021449

對(duì)于實(shí)現(xiàn)以下幾個(gè)函數(shù),可以從幾個(gè)方面思考
不傳入第一個(gè)參數(shù),那么默認(rèn)為 window。改變了 this 指向,讓新的對(duì)象可以執(zhí)行該函數(shù)。那么思路是否可以變成給新的對(duì)象添加一個(gè)函數(shù),然后在執(zhí)行完以后刪除?

  • 如何實(shí)現(xiàn)一個(gè)call函數(shù)
Function.prototype.myCall = function (context) {
  var context = context || window
  // 給 context 添加一個(gè)屬性
  // getValue.call(a, 'yck', '24') => a.fn = getValue
  context.fn = this
  // 將 context 后面的參數(shù)取出來
  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
}
  • 如何實(shí)現(xiàn)一個(gè)apply函數(shù)
Function.prototype.myApply = function (context) {
  var context = context || window
  context.fn = this

  var result
  // 需要判斷是否存儲(chǔ)第二個(gè)參數(shù)
  // 如果存在,就將第二個(gè)參數(shù)展開
  if (arguments[1]) {
    result = context.fn(...arguments[1])
  } else {
    result = context.fn()
  }

  delete context.fn
  return result
}
  • 如何實(shí)現(xiàn)一個(gè)bind函數(shù)
Function.prototype.myBind = function (context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  var _this = this
  var args = [...arguments].slice(1)
  // 返回一個(gè)函數(shù)
  return function F() {
    // 因?yàn)榉祷亓艘粋€(gè)函數(shù),我們可以 new F(),所以需要判斷
    if (this instanceof F) {
      return new _this(...args, ...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)容