最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

再談JavaScript中bind、call、apply三個(gè)方法的區(qū)別與使用方式

 更新時(shí)間:2022年05月03日 11:47:48   作者:Ahuiyo の Blog  
這篇文章主要介紹了Javascript中bind、call、apply三個(gè)方法的使用方式,需要的朋友可以參考下

call的基本使用

var ary = [12, 23, 34];
ary.slice();

以上兩行簡(jiǎn)單的代碼的執(zhí)行過(guò)程為:ary這個(gè)實(shí)例通過(guò)原型鏈的查找機(jī)制找到Array.prototype上的slice方法,讓找到的slice方法執(zhí)行,在執(zhí)行slice方法的過(guò)程中才把ary數(shù)組進(jìn)行了截取。

注意slice方法執(zhí)行之前有一個(gè)在原型上查找的過(guò)程(當(dāng)前實(shí)例中沒(méi)有找到,再根據(jù)原型鏈查找)。

當(dāng)知道了一個(gè)對(duì)象調(diào)用方法會(huì)有一個(gè)查找過(guò)程之后,我們?cè)倏矗?/p>

var obj = {name:'iceman'};
function fn() {
    console.log(this);
    console.log(this.name);
}
fn(); // this --> window
// obj.fn(); // Uncaught TypeError: obj.fn is not a function
fn.call(obj);

call方法的作用:首先尋找call方法,最后通過(guò)原型鏈在Function的原型中找到call方法,然后讓call方法執(zhí)行,在執(zhí)行call方法的時(shí)候,讓fn方法中的this變?yōu)榈谝粋€(gè)參數(shù)值obj,最后再把fn這個(gè)函數(shù)執(zhí)行。

知道這個(gè)原型上的原理后,咱們就可以動(dòng)手分析實(shí)現(xiàn)這三個(gè)方法了。

bind、call、apply 區(qū)別

  • call 和 apply 都是為了解決改變 this 的指向。作用都是相同的,只是傳參的方式不同。
  • 除了第一個(gè)參數(shù)外,call 可以接收一個(gè)參數(shù)列表,apply 只接受一個(gè)參數(shù)數(shù)組
let a = {
    value: 1
}
function getValue(name, age) {
    console.log(name)
    console.log(age)
    console.log(this.value)
}
getValue.call(a, 'yck', '24')
getValue.apply(a, ['yck', '24'])

bind 和其他兩個(gè)方法作用也是一致的,只是該方法會(huì)返回一個(gè)函數(shù)。并且我們可以通過(guò) bind 實(shí)現(xiàn)柯里化

如何實(shí)現(xiàn)一個(gè) bind 函數(shù)

對(duì)于實(shí)現(xiàn)以下幾個(gè)函數(shù),可以從幾個(gè)方面思考

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

當(dāng)然是肯定的,于是我們可以這樣寫:

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))
  }
}

如何實(shí)現(xiàn)一個(gè) call 函數(shù)

Function.prototype.myCall = function (context,...arg) {
  var context = context || window  // 給 context 添加一個(gè)屬性
  // getValue.call(a, 'yck', '24') => a.fn = getValue
  //使用symbol 選擇一個(gè)獨(dú)一無(wú)二的值作為新添加的屬性
  let symbol = new Symbol();
  context[symbol] = this;
  let result = context[symbol](...arg)
  // 刪除添加的函數(shù)
  delete context[symbol]  
  return result
}

如何實(shí)現(xiàn)一個(gè)apply 函數(shù)

apply實(shí)現(xiàn)原理與call實(shí)現(xiàn)基本類似,只有傳值的方式不一樣。

Function.prototype.myApply = function (context,arg) {
  var context = context || window // 給 context 添加一個(gè)屬性
 // getValue.call(a, 'yck', '24') => a.fn = getValue
 //使用symbol 選擇一個(gè)獨(dú)一無(wú)二的值作為新添加的屬性
 let symbol = new Symbol();
 context[symbol] = this;
 let result = context[symbol](arg)
 // 刪除添加的函數(shù)
 delete context[symbol]
 return result
}

經(jīng)過(guò)對(duì)以上的函數(shù)進(jìn)行檢測(cè) , 完美通過(guò)。

const obj = {  
 name : 'xiaoxiao',  
 getName : function (arg) {  
 console.log(`我是${this.name}里面的,我里面有${arg}`);  
 }  
}  
obj.getName([0,0,0,0,0]); // 我是xiaoxiao里面的  
const obj2 = {  
 name : 'huahua'  
}  
//傳值不一樣  
obj.getName.myCall(obj2,1,1,1,1,1,1);  
obj.getName.myBind(obj2)(2,2,2,2,2,2);  
obj.getName.myApply(obj2,[3,3,3,3,3,3]);

 更多關(guān)于JS中call、apply三個(gè)方法的區(qū)別與使用方式請(qǐng)查看下面的相關(guān)鏈接

相關(guān)文章

最新評(píng)論

彰武县| 寻甸| 郎溪县| 黎川县| 缙云县| 安宁市| 沙湾县| 舞钢市| 阿拉尔市| 师宗县| 扎囊县| 南江县| 南平市| 玉山县| 桐庐县| 石嘴山市| 大姚县| 重庆市| 上蔡县| 苏尼特左旗| 丽江市| 昌乐县| 阿瓦提县| 龙门县| 石城县| 呼玛县| 雷波县| 阿拉善右旗| 杭锦后旗| 保德县| 惠东县| 永胜县| 根河市| 利川市| 曲松县| 同德县| 博白县| 家居| 石景山区| 登封市| 财经|