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

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

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

call的基本使用

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

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

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

當(dāng)知道了一個對象調(diào)用方法會有一個查找過程之后,我們再看:

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方法,最后通過原型鏈在Function的原型中找到call方法,然后讓call方法執(zhí)行,在執(zhí)行call方法的時候,讓fn方法中的this變?yōu)榈谝粋€參數(shù)值obj,最后再把fn這個函數(shù)執(zhí)行。

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

bind、call、apply 區(qū)別

  • call 和 apply 都是為了解決改變 this 的指向。作用都是相同的,只是傳參的方式不同。
  • 除了第一個參數(shù)外,call 可以接收一個參數(shù)列表,apply 只接受一個參數(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 和其他兩個方法作用也是一致的,只是該方法會返回一個函數(shù)。并且我們可以通過 bind 實現(xiàn)柯里化

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

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

  • 不傳入第一個參數(shù),那么默認(rèn)為 window
  • 改變了 this 指向,讓新的對象可以執(zhí)行該函數(shù)。那么思路是否可以變成給新的對象添加一個函數(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)
  // 返回一個函數(shù)
  return function F() {
    // 因為返回了一個函數(shù),我們可以 new F(),所以需要判斷
    if (this instanceof F) {
      return new _this(...args, ...arguments)
    }
    return _this.apply(context, args.concat(...arguments))
  }
}

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

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

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

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

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

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

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三個方法的區(qū)別與使用方式請查看下面的相關(guān)鏈接

相關(guān)文章

最新評論

大城县| 井研县| 谷城县| 宁海县| 平原县| 久治县| 将乐县| 余江县| 房产| 聊城市| 天台县| 古田县| 遂昌县| 正镶白旗| 博野县| 澄城县| 理塘县| 巩义市| 清水河县| 塔城市| 张掖市| 福海县| 黔江区| 泉州市| 乌鲁木齐县| 罗源县| 阿勒泰市| 潮安县| 娄烦县| 资阳市| 姜堰市| 佛学| 衡阳县| 库车县| 屯昌县| 颍上县| 晋城| 菏泽市| 昭觉县| 玛纳斯县| 抚州市|