javascript中call()、apply()與bind()的實現原理解析

  • 由於call()apply()bind()都是屬於Function.prototype對象下的方法,所以每個function實例都擁有有callapplybind屬性。
  • 相同點:都是爲改變this指向而存在的
  • 異同點:使用call()方法時,傳遞給函數的參數必須逐個列舉出來,使用apply()方法時,傳遞給函數的是參數數組。bind()call()很相似,第一個參數是this的指向,從第二個參數開始是接收的參數列表。bind() 方法不會立即執行,而是返回一個改變了上下文 this後的函數,用於稍後調用。 call()apply()則是立即調用。
1、call實現原理:
Function.prototype.mycall = function (context) {
    // 當context爲null時,其值則爲window
    context = context || window;
    // this爲調用mycall的函數。將this賦值給context的fn屬性
    context.fn = this;
    // 將arguments轉爲數組,並從下標1位置開如截取
    let arg = [...arguments].slice(1);
    // 將arg數組的元素作爲fn方法的參數執行,結果賦值給result
    let result = context.fn(...arg);
    // 刪除fn屬性
    delete context.fn;
    // 返回結果
    return result;
}

測試:

function add(c, d){
    return this.a + this.b + c + d;
}
var obj = {a:1, b:2};
console.log(add.mycall(obj, 3, 4)); // 10
2、apply實現原理
Function.prototype.myapply = function (context) {
    // 當context爲null時,其值則爲window
    context = context || window
    // this爲調用myapply的函數。將this賦值給context的fn屬性
    context.fn = this;
    // 如果未傳值,則爲一空數組
    let arg = arguments[1] || [];
    // 將arg數組的元素作爲fn方法的參數執行,結果賦值給result
    let result = context.fn(...arg);
    // 刪除fn屬性
    delete context.fn
    // 返回結果
    return result
}
測試:
function add(c, d){
    return this.a + this.b + c + d;
}
var obj = {a:1, b:2};
console.log(add.myapply(obj, [5, 6])); // 14
3、bind實現原理
Function.prototype.mybind = function (context) {
    // this爲調用mybind的函數。將this賦值給變量_this
    let _this = this;
    // 將arguments轉爲數組,並從下標1位置開如截取
    let arg = [...arguments].slice(1);
    // 返回函數fn
    return function fn(){
        // 通過apply方法調用函數並返回結果。
        return _this.apply(context, arg.concat(...arguments));
    }
}

測試:

var obj = {
    siteName: "zhangpeiyue.com"
}
function printSiteName() {
    console.log(this.siteName);
}
var site = printSiteName.mybind(obj);
// 返回的是一個函數
console.log(site) // function () { … }
// 通過mybind使其this發生了變化
site();// zhangpeiyue.com

—————END—————
喜歡本文的朋友們,歡迎關注公衆號 張培躍,收看更多精彩內容!!!公衆號回覆 電子書 ,送你經典電子書籍!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章