40 – 真正理解 Bind、Call 和 Apply


原文地址:https://dev.to/bhagatparwinder/truly-understand-bind-call-apply-21da

Bind

JavaScript 中的 this 扮演者重要的角色,在 JavaScript 中它是依據(jù)函數(shù)是怎么被調(diào)用的而不是它在哪聲明的(箭頭函數(shù)則表現(xiàn)為相反)。

我們舉一個例子來示范一下 this 是如何工作的:

const sayGreeting = {    name: "Parwinder",    hello: function() {        return `Hello, ${this.name}`;    }}console.log(sayGreeting.hello()); // Hello, Parwinder

hello 方法可以獲取 sayGreeting 上的 name 屬性,當(dāng)我用 sayGreeting 調(diào)用它時,它是運行在 sayGreeting 對象上下文中的。

相反如果我這樣做:

const sayGreeting = {    name: "Parwinder",    hello: function() {        return `Hello, ${this.name}`;    }}const hello = sayGreeting.hello;console.log(hello === sayGreeting.hello); // trueconsole.log(hello()); // Hello, undefined

盡管 hello 變量與 sayGreeting 對象上的 hello 方法相等,但它的執(zhí)行上下文并不是在 sayGreeting 中,而是在 window 或全局狀態(tài)中。

bind 方法允許我們綁定上下文,它返回一個新的方法且上下文綁定為我們傳遞給 bind 函數(shù)的內(nèi)容。

const sayGreeting = {    name: "Parwinder",    hello: function() {        return `Hello, ${this.name}`;    }}const hello = sayGreeting.hello.bind(sayGreeting);console.log(hello()); // Hello, Parwinder

實際業(yè)務(wù)中哪里需要使用 bind?

上面的所有例子,數(shù)據(jù)的獲取和方法的調(diào)用都在一個對象上 bind 的作用并不明顯。可有時候當(dāng)你需要向一個對象借一個方法但運行上下文需要在另一個對象中時,你就需要使用 bind。

const sayGreeting = {    name: "Parwinder",    hello: function () {        return `Hello, ${this.name}`;    }}const nameObject = {    name: "Lauren"}const hello = sayGreeting.hello.bind(nameObject);console.log(hello()); // Hello, Lauren

sayGreeting 對象上有 hello 方法,所以在 nameObject 對象上就沒有必要再寫一個相同的方法。我可以向 sayGreeting 對象借用它然后運行在 nameObject 上下文中。

Call

callapplybind 是有區(qū)別的,bind 返回一個新的方法而 callapply 則立即調(diào)用執(zhí)行方法。callthis 作為第一個參數(shù),其他參數(shù)需要一個個的傳遞。它們都會傳遞到我們調(diào)用的函數(shù)中:

const sayGreeting = {    name: "Parwinder",    hello: function () {        return `Hello, ${this.name}`;    }}console.log(sayGreeting.hello.call(sayGreeting)); // Hello, Parwinder

帶有其它參數(shù):

const sayGreeting = {    name: "Parwinder",    hello: function (trait, color) {        return `Hello, ${this.name}. I see you ${trait} ${color}. It is my favorite too!`;    }}console.log(sayGreeting.hello.call(sayGreeting, "like", "red"));// Hello, Parwinder. I see you like red. It is my favorite too!

Apply

盡管 applycall 類似都是直接執(zhí)行函數(shù),但它接受的是一個數(shù)組作為第二個參數(shù)而不是逗號分隔的值。

const sayGreeting = {    name: "Parwinder",    hello: function () {        return `Hello, ${this.name}`;    }}console.log(sayGreeting.hello.apply(sayGreeting)); // Hello, Parwinder

當(dāng)沒有其余參數(shù)時 applycall 沒有區(qū)別,但是當(dāng)我們有其余參數(shù)時,使用方法就有點區(qū)別:

const sayGreeting = {    name: "Parwinder",    hello: function (trait, color) {        return `Hello, ${this.name}. I see you ${trait} ${color}. It is my favorite too!`;    }}console.log(sayGreeting.hello.apply(sayGreeting, ["like", "red"]));// Hello, Parwinder. I see you like red. It is my favorite too!

apply 使得傳遞多個參數(shù)變得更容易些,但是現(xiàn)在 ES6 中使用擴展運算符傳遞多個參數(shù)也很容易了。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容