一個簡單的例子讓你很輕鬆地明白JavaScript中apply、call、bind三者的用法及區別

引言

這是個人第一篇前端面試題文章,也是用來幫助本身鞏固複習知識, 在以後但願拿到本身滿意的offer,這第一篇講的就是一道常見的面試題,關於JavaScript中apply、call、bind三者的用法及區別。javascript

正文

若是有不想看過程的小夥伴能夠直接跳到 總結前端

1、apply、call、bind的共同用法

先將一下特別概念性的,三者的共同用法就是能夠改變函數的this指向,將函數綁定到上下文中。接下來看一個普通的應用場景:java

let obj1 = {
    my_favorite : 'banana',
    add: function (fruit) {
        console.log('我喜歡的水果是' + fruit + ',可是我最愛的水果是' + this.my_favorite)
    }
}

let obj2 = {
	my_favorite: 'orange'
}

obj1.add('apple')
//輸出結果爲: 我喜歡的水果是apple,可是我最愛的水果是banana

能夠看到最後一行代碼咱們調用了obj1中的add函數,並傳入了一個參數apple。add函數中的 this 指的是他所在的對象obj1,因此this.my_favorite 就是banana, 可是咱們若是想得到obj2中的my_favorite, 該怎麼辦呢?接下來看一下每一個函數的用法吧~web

2、 apply

語法:fun.apply(obj,[arry])面試

  • 第一個參數: 傳入的是this須要指向的對象
  • 第二個參數: 傳入的是一個數組,做爲 fun 函數的參數
let obj1 = {
    my_favorite : 'banana',
    add: function (...fruit) {  //...fruit 表示的意思是可接收多個參數
        console.log('我喜歡的水果是' + fruit + ',可是我最愛的水果是' + obj2.my_favorite)
    }
}

let obj2 = {
    my_favorite: 'orange'
}


obj1.add.apply(obj2, ['apple', 'Watermelon'])
//輸出結果爲:我喜歡的水果是apple,Watermelon,可是我最愛的水果是orange

obj1.add.apply(obj2, ['apple', 'Watermelon'])
這一行代碼, 第一個參數將obj1中的add函數的 this 指向了obj2 , 第二個參數以數組形式傳入多個參數,做爲 obj1 中的 add 函數傳入的參數, 因此最後能將 apple 和 watermelon 都輸出。數組

3、 call

語法:fun.call(obj,[arg1, arg2, arg3...,argN]app

  • 第一個參數: 傳入的是this須要指向的對象
  • 其他參數: 除了第一個參數,其餘的參數都是做爲 fun 的傳入參數

call 和 apply 惟一的區別就是在於給 fun 函數傳入參數的形式不一樣, call是將多個參數逐個傳入, apply 是 將多個參數放在一個數組中,一塊兒傳入svg

話很少說,直接來看看 call 的例子:函數

let obj1 = {
    my_favorite : 'banana',
    add: function (...fruit) {
        console.log('我喜歡的水果是' + fruit + ',可是我最愛的水果是' + obj2.my_favorite)
    }
}

let obj2 = {
    my_favorite: 'orange'
}


obj1.add.call(obj2, 'apple', 'Watermelon')
//輸出結果爲:我喜歡的水果是apple,Watermelon,可是我最愛的水果是orange

你們能夠對比一下 call 和 apply 的區別到底在哪裏ui

4、 bind

語法:fun.bind(obj)(arg)

  • bind的第一個參數:傳入的是this須要指向的對象
  • 由於函數bind返回的是一個函數,即將 fun 的 this 指向 obj 後不進行自身調用, 咱們須要本身進行一次調用, 因此要在函數bind後面再加一個小括號進行自身調用, 而小括號裏則能夠輸出傳給 fun 函數的參數, 輸入的能夠是數組形式的,也能夠是逐個傳入的。

簡單看一下例子:

let obj1 = {
    my_favorite : 'banana',
    add: function (...fruit) {
        console.log('我喜歡的水果是' + fruit + ',可是我最愛的水果是' + obj2.my_favorite)
    }
}

let obj2 = {
    my_favorite: 'orange'
}


obj1.add.bind(obj2)('apple', 'Watermelon')
obj1.add.bind(obj2)(['apple', 'Watermelon'])
//輸出結果爲:我喜歡的水果是apple,Watermelon,可是我最愛的水果是orange
//輸出結果爲:我喜歡的水果是apple,Watermelon,可是我最愛的水果是orange

能夠很清楚的看到, bind 有點相似 apply 和 call 的結合,只不過它返回的是一個函數,須要本身進行一下調用, 而傳給 fun 函數的參數形式能夠是像 apply 同樣的數組形式, 也能夠是像 call 同樣的逐個傳入的形式。

5、其餘應用場景

  • 獲取一個數組中的最大值或最小值
/* 普通狀況,咱們是這樣獲取數組中的最大值、最小值的 */

let max = Math.max(22, 33, 54, 88, 35, 44, 78, 80)
let min = Math.min(22, 33, 54, 88, 35, 44, 78, 80)
console.log(max, min)
//88 22

有沒有感受特別的麻煩,那接下來看看使用了這幾個函數以後是什麼樣子的吧

/* 使用函數apply */
let arr = [22, 33, 54, 88, 35, 44, 78, 80]
let max = Math.max.apply(null, arr)
let min = Math.min.apply(null, arr)
console.log(max, min)
//88 22

這樣看着是否是特別的簡潔,由於咱們不須要把arr 中的數組一個個傳入進行比較,而是直接以數組形式傳入就能夠了。

6、總結

  1. apply、call、bind 三者都是能夠改變函數的this指向的
  2. apply 和 call 都是改變函數this指向,並傳入參數後當即調用執行該函數
  3. bind 是在改變函數this指向,並傳入參數後返回一個新的函數,不會當即調用執行
  4. apply 傳入的參數是數組形式的;call 傳入的參數是按順序的逐個傳入並以逗號隔開; bind 傳入的參數既能夠是數組形式,也能夠是按順序逐個傳入。

結束語

apply、call、bind三者的用法及區別是常常考到的一道面試題,但願對你們有所幫助。以後我還會天天更新一個前端面試題,來幫助你們以及我本身鞏固知識點,喜歡的小夥伴能夠點個關注, 但願大家都拿到本身滿意的offer

相關文章
相關標籤/搜索