iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
自我挑戰組

登堂入室!前端工程師的觀念技術 _30_ 題系列 第 6

5. bind, call, apply 的差異

在回答問題前,我們可以先了解他們是做什麼用的,為什麼總是拿來被比較?

這裡要先回憶一個觀念: JS裡,所有的 函式 (function) 都是物件(object)。

Function objects inherit from Function.prototype. Function.prototype cannot be modified.
引用自Function.prototype | MDN

『 Function.prototype 這個屬性,表示 Function 的原型物件,』
『 所有的Function物件都繼承自Function.prototype ,且Function.prototype不能被修改。』

bind(), call(), apply() 是 Function.prototype 內建的方法(method),
被用來指定函式中this的指向。

那來依序看看它們的作用吧:

bind


bind()建立一個新的函式(function),使這個函式中的this被綁定至傳入 bind()的 參數(parameter)。

定義

Creates a new function which, when called, has its this set to the provided value, with a given sequence of arguments preceding any provided when the new function was called.

舉例:

let mary = {
    name: "Mary",
    age: 22,
}

function getAge() {
    console.log(this.age);
}

let getMarysAge = getAge.bind(mary);

getMarysAge();   // output: 22

觀念 :

  1. getAge是一個function,也是一個object。
  2. getAge裡的thiskeyword綁定給Mary,並創造新的functiongetMarysAge

call


call()直接呼叫(執行)一個函式,並將傳入的值設為該函式的this。

定義

Calls (executes) a function and sets its this to the provided value, arguments can be passed as they are.

舉例:

let mary = {
    name: "Mary",
    age: 22,
}

function getAge() {
    console.log(this.age);
} 

getAge.call(mary); // output: 22

vs. bind : call不會直接回傳function,所以不需要給定variable就會直接執行。

那如果要執行call的函式,本身就需要傳入參數的話,要怎麼辦呢?

補充個有參數的例子:

let mary = {
    name: "Mary",
    age: 22,
}

function getAge(country, career) {
    console.log("She is " + this.age + " years old");  
    console.log("She is a " + career + " from " + country); 
}

getAge.call(mary, "Korean", "student");
// output: She is 22 years old ; She is a student from Korean

apply


apply() 會直接呼叫(執行)一個函式,並將傳入的值設為該函式的this。而傳入參數的形式是array。

定義

Calls a function and sets its this to the provided value, arguments can be passed as an Array object.

舉例:

let mary = {
    name: "Mary",
    age: 22,
}

function getAge(country, career) {
    console.log("She is " + this.age + " years old");  
    console.log("She is a " + career + " from " + country); 
}

getAge.apply(mary, ["Korean", "student"]); 
// output: She is 22 years old ; She is a student from Korean

vs. call : parameter以陣列放入。

結論


由此可知,我們可以知道:

  • bind, call, apply 的共通點是,都能綁定函式中this的指向。
  • 差異是
    1. bind 會 創造(回傳)新的函式,call 和 apply 則是呼叫函式。
    2. call 可以 直接 依序傳入原來函式的參數,apply 的參數則必須用 [array] 傳遞。

【如內文有誤還希望請不吝指教>< 謝謝閱覽至此的各位:D 】

-----正文結束-----

prototype 翻譯成原型,通常是研發完畢、在投入量產前完成的產品模型,

但它不是產品也不是模型。我上產品設計第一次聽到這個詞,問老師: 那是樣品的意思嗎? 他說不是。
(產品:拿來賣的。/模型:研發時模擬外觀用的。/樣品:給客人觀賞用的。)
不知道有沒有人跟我一樣困惑過這個詞,但我覺得在JS裡面,prototype被解釋的比較好懂。

講那麼多,我只是在想明天可以寫prototype。


上一篇
4. 關於 Constructor Function
下一篇
6. Prototypal inheritance 的運作原理
系列文
登堂入室!前端工程師的觀念技術 _30_ 題31

尚未有邦友留言

立即登入留言