JavaScript中的call,apply,bind學習總結

JavaScript 中的 call, apply, bind 這三個函數的做用和區別在各大論壇都被討論了不少次了,可是我一直都還沒來得及好好總結,此次正好看到了一個很不錯的關於JavaScript 中 apply 、call 的詳解,本身就學習並總結了一波~,正好更新一波博客😂javascript

call 和 apply

其實 call 和 apply 的做用很明確,就是要經過對它們傳入的參數來肯定函數上下文的對象,也就是經過參數來肯定函數中的 this 關鍵字的指向,this 關鍵字是 JavaScript 中一個很重要、很值得咱們去加深學習和理解的東西,具體關於 this 的知識總結,我之前寫了一個博客,感興趣的話請參考淺析JavaScript中的this關鍵字java

call 和 apply 的做用是相同的,它們的惟一區別就是對傳入參數的格式要求不一樣。git

  • call()github

    call 方法在調用的時候,須要傳入一個函數的上下文對象和一個參數列表數組

    let obj = {
        name: 'nicole'
    }
    let func = function (){
        console.log(this.name)
        console.log(arguments)
    }
    func.call(obj,{age: '20'},{id: '1'}) 
    // 運行結果是打印出 nicole 和 [{age: "20"},{id: '1'}]
    複製代碼

    函數的上下文被指向了傳入的第一個參數obj,若是咱們直接調用func(obj,{age: '20'},{id: '1'}),那麼函數的 this 則指向了 window (嚴格模式下爲 undefined)。app

  • apply()函數

    apply方法在調用的時候,須要傳入一個函數的上下文對象和一個數組學習

    let obj = {
        name: 'nicole'
    }
    let func = function (){
        console.log(this.name)
        console.log(arguments)
    }
    func.apply(obj,[{age: '20'},{id: '1'}]) 
    // 運行結果是打印出 nicole 和 [{age: "20"},{id: '1'}]
    複製代碼

    因爲callapply方法的做用都是同樣的,因此在決定究竟要用哪一個的時候,咱們能夠直接從參數的形式來考慮,若是咱們要傳入的參數是數組,那咱們就直接使用apply就好。ui

bind

callapply方法不一樣的是,callapply方法在被調用時就直接執行了當前的函數,而bind直接返回了一個改變了函數上下文以後的新函數,這個新函數與原函數並不是是同一個函數,並且與call相似,bind方法接受列表形式的參數this

let obj = {
    name: 'nicole'
}
let func1 = function (){
    console.log(this)
}
let func2 = func1.bind(obj,{age: '20'})
func1 === func2 // false
func2() // {name: "nicole"}
複製代碼

咱們能夠本身實現一個bind函數

Function.prototype.bindTest = function () {
    let self = this;
    let context = Array.prototype.shift.call(arguments);
    let arg = Array.prototype.slice.call(arguments);
    return function () {
        self.apply(context, [...arg, ...arguments]);
    }
}
let obj = {
    name: 'nicole'
}
let func1 = function () {
    console.log(this);
    console.log(arguments);
}
let func2 = func1.bindTest(obj)
func2({age: 11});
// 運行結果 {name: "nicole"} [{age: 11}]
複製代碼

值得注意的是,bind方法返回的函數裏面的 this 值不能夠再被改變了,也就是說不能再修改函數的上下文,無論再對函數調用call仍是apply,都沒法再改變函數的上下文。而普通的函數則能借助call仍是apply各類肆意的修改函數的上下文。

let obj1 = {
	name: 'nicole'
}
let obj2 = {
	name: 'neil'
}
let func = function (){
	console.log(this)
}
let func1 = func.bind(obj1)
func1.call(obj2) 
// 運行結果是{name: "nicole"},也就是說雖然調用了func1的 call 方法,可是函數上下文依然是obj1

func.call(obj1) // {name: "nicole"}
func.call(obj2) // {name: "neil"}

func.apply(obj1) // {name: "nicole"}
func.apply(obj2) // {name: "neil"}
複製代碼
相關文章
相關標籤/搜索