新手理解 apply 和 call

圈圈Dei圈發表於2019-01-29

說點題外話

本文僅適合新手, 我是說很新的那種, 旨在和大家共同瞭解js的call和apply方法. 筆者水平有限, 文中不免會有疏漏, 大神請輕噴.

2019-01-29-11-00-19

開始說正事

apply 和 call 都是 JS 函式物件的原型方法, 因此我們可以在任何的函式呼叫這兩個方法, 主要作用就是使得物件能夠借用到本來不屬於他的方法(就是物件的本領). 有點懵逼是不是? 下邊我們來舉個栗子.

2019-01-29-15-59-30

狗急跳牆

假設我們有一隻喵星人:

const cat = {
    // 它的名字叫 cat
    name: 'cat',
    // 它可以跑
    run() {
        console.log(`${this.name} can run`)
    },
    // 還可以跳(包括跳牆是可以的)
    jump() {
        console.log(`${this.name} can jump`)
    }
}
複製程式碼

同時, 它還有一個小夥伴汪星人:

const dog = {
    // 汪星人叫 dog
    name: 'dog',
    // 會跑
    run() {
        console.log(`${this.name} can run`)
    },
    // 還會吠
    bark() {
        console.log(`${this.name} bark loudly`)
    },
    // 馬戲團的?, 還會做算數
    count(a, b) {
        console.log(`${a} + ${b} = ${a + b}`)
    }
}
複製程式碼

不難發現, 貓狗各有所長. 貓咪可以跳牆, 但是 ?? 可以吠叫. 假如, 現在的情況提別緊急, 緊急到了什麼地步呢. 大家都要到牆頭上才能保證安全. 這個時候貓咪直接

cat.jump()
複製程式碼

2019-01-29-16-11-45
成功翻上牆頭.

然而, 現在 ?? 就尷尬了. 跳上牆頭??? 不會

2019-01-29-16-15-12

就一個 bark() 喊半天也沒有用呀!!!

這個時候 apply 就派上用場了. 我們執行

cat.jump.apply(dog)
複製程式碼

2019-01-29-16-22-32
?? 也順利脫險啦. 跳上了牆頭, 狗狗歡快的 bark() 這時候貓咪不樂意了, 它也想吠叫, 但是沒有這個本領. 這時候??也大方的借出了自己的 bark 本領給了貓咪.

dog.bark.apply(cat)
複製程式碼

2019-01-29-16-27-17
兩隻小可愛歡快的在牆頭上叫起來 ^_^.

apply方法的原理

apply方法可以當作是一種方法的借調: 也就是說把某個方法引用到不包含它的某個物件上. 方法(函式)是用來被物件呼叫才能夠執行的, 而apply恰恰指向了呼叫當前方法的物件. 初學者可能會誤認為apply是對向繼承了之前引用的方法. 然而, 這裡不太建議這樣理解. 我們可以再次利用狗狗物件呼叫jump方法, 得到的結果如下圖所示:

2019-01-29-16-31-04
狗狗, 並沒有學會 jump 的本領, 它只是在緊急時刻借用了貓咪的跳牆方法.

需要引數

我們知道我們的 ?? 來自馬戲團, 具備了算數的能力. 不信試試?

dog.count(1, 2)
複製程式碼

2019-01-29-16-47-53

簡直了不得, 有木有? 然而, 喵星人現在也想要去馬戲團. 可是它不會算數, 就需要從汪星人那裡借來 count 本領. 那麼就尷尬了.

2019-01-29-16-51-57

既然要算加法, 就需要把兩個加數給人家嘛. 怎麼給呢? 只需要把 count 方法需要的引數拼接到一個陣列裡就可以啦. 就像醬紫.

2019-01-29-16-53-28

那麼 call 方法咧

其實 call 方法和 apply 方法用法幾乎完全一致, 為什麼是幾乎呢? 在傳遞引數的時候. 剛剛我們用到的 apply 方法需要把算數的引數放到一個陣列裡告訴 count 方法. 用 call 的時候就方便多了. 直接擼.

2019-01-29-16-56-23

這個樣式兒. 簡直是舒服呀!

2019-01-29-16-57-56

相關文章