成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【譯】this 是什么?JavaScript 對象的內(nèi)部工作原理

Hwg / 3065人閱讀

摘要:關(guān)鍵字會實(shí)例化一個新的對象實(shí)例,并在執(zhí)行構(gòu)造函數(shù)時將指向該實(shí)例。原文鏈接譯是什么對象的內(nèi)部工作原理

原文鏈接:What is this? The Inner Workings of JavaScript Objects (需要梯子)

原文作者:Eric Elliott

譯文永久鏈接:【譯】什么是 this?JavaScript 對象的內(nèi)部工作原理

譯者:士心

翻譯目的:函數(shù)動態(tài)綁定 this 的特性,經(jīng)常讓開發(fā)者感到頭疼,這篇文章能幫助梳理概念

JavaScript 是一種支持面向?qū)ο缶幊毯蛣討B(tài)綁定的多范式語言。動態(tài)綁定是其一個強(qiáng)大的特性,它允許 JavaScript 代碼在運(yùn)行時更改 this,但是這一強(qiáng)大而且靈活的特性卻會給開發(fā)者帶來一些困惑,這些困惑集中在 JavaScript 代碼運(yùn)行時的表現(xiàn)上。

動態(tài)綁定(Dynamic Binding)

動態(tài)綁定指的是在運(yùn)行時才確定調(diào)用函數(shù)的方式,而不是更早的編譯階段。JavaScript 通過 this 和原型鏈來體現(xiàn)動態(tài)綁定。也就是說,函數(shù)內(nèi)部的 this 是在運(yùn)行時確定,并且定義函數(shù)的方式不同,確定 this 的規(guī)則也不同。

先來玩?zhèn)€游戲。這個游戲叫 “this 是什么?”

const a = {
  a: "a"
};
const obj = {
  getThis: () => this,
  getThis2 () {
    return this;
  }
};
obj.getThis3 = obj.getThis.bind(obj);
obj.getThis4 = obj.getThis2.bind(obj);
const answers = [
  obj.getThis(),
  obj.getThis.call(a),
  obj.getThis2(),
  obj.getThis2.call(a),
  obj.getThis3(),
  obj.getThis3.call(a),
  obj.getThis4(),
  obj.getThis4.call(a)
];

在繼續(xù)之前,請先寫下你的答案。完成后,console.log()你的答案,你答對了嗎?

譯者注:本文的示例需要運(yùn)行在 ES6 Module 下才符合文章所說的結(jié)果,你可以在 HTML 頁面中指定腳本標(biāo)簽類型 ... 讓代碼運(yùn)行在 ES6 Module 下。如果你將代碼直接復(fù)制到瀏覽器控制臺運(yùn)行,下文說的 undefined 實(shí)際上是 window。

讓我們從第一個結(jié)果開始。obj.getThis() 返回 undefined,但為什么呢?箭頭函數(shù)永遠(yuǎn)不會綁定屬于自己的 this,它們的 this 總是綁定在定義時所在的作用域上。本例中的定義時所在的作用域,就是 ES6 模塊的根作用域,這里的 thisundefined。因?yàn)橄嗤脑颍?b>obj.getThis.call(a) 同樣也是 undefined。對于箭頭函數(shù),它的 this 不能被重新分配賦值,即使使用 .call().bind(),它的 this 總是綁定在定義時所在的作用域上,而不會指向運(yùn)行時所在的作用域。

obj.getThis2() 通過一般的函數(shù)調(diào)用獲取其綁定。如果函數(shù)之前沒有綁定 this(就是說,它不是箭頭函數(shù)),那該函數(shù)就可以擁有自己的 this 綁定,具體綁定到使用 .[] 調(diào)用該方法的對象上。

obj.getThis2.call(a) 做了點(diǎn)小動作,call() 方法提供給定的 this 值和可選參數(shù)調(diào)用函數(shù)。換句話說,函數(shù)從 .call() 參數(shù)獲取 this 的綁定,因此 obj.getThis2.call(a) 返回 a 對象。

使用 obj.getThis3 = obj.getThis.bind(obj);,我們嘗試綁定一個箭頭函數(shù),前面我們已經(jīng)討論過綁定箭頭函數(shù)是不起作用的,所以 obj.getThis3()obj.getThis3.call(a) 都得到 undefined。

我們可以綁定一般的函數(shù),所以 obj.getThis4() 按預(yù)期返回 obj,因?yàn)樗呀?jīng)使用 obj.getThis4 = obj.getThis2.bind(obj); 綁定了。而 obj.getThis4.call(a) 遵從第一個的綁定,所以返回 obj 而不是 a。

加大難度(Curve Ball)

同樣的挑戰(zhàn),不過這一次,使用到了 class 的公共字段語法(public fields syntax) (寫這篇文章的時候,該語法提案處于 Stage3 階段。Chrome 和 @babel/plugin-proposal-class-properties 已經(jīng)支持):

譯者注:公共字段語法(public fields syntax),如果不知道是什么的話,可以看阮一峰 ES6 | Class 的基本語法: 實(shí)例屬性的新寫法
class Obj {
  getThis = () => this
  getThis2 () {
    return this;
  }
}
const obj2 = new Obj();
obj2.getThis3 = obj2.getThis.bind(obj2);
obj2.getThis4 = obj2.getThis2.bind(obj2);
const answers2 = [
  obj2.getThis(),
  obj2.getThis.call(a),
  obj2.getThis2(),
  obj2.getThis2.call(a),
  obj2.getThis3(),
  obj2.getThis3.call(a),
  obj2.getThis4(),
  obj2.getThis4.call(a)
];

在繼續(xù)之前寫下你的答案。

準(zhǔn)備好了?

除了 obj2.getThis2.call(a) 返回 a 對象外,其它都返回對象實(shí)例。箭頭函數(shù)的 this 仍然綁定在定義時所在的作用域上,區(qū)別在于定義時所在作用域的 this 已然不是 undefined。這段代碼的底層,會將類的屬性賦值編譯成:

class Obj {
  constructor() {
    this.getThis = () => this;
  }
...

也就是說,箭頭函數(shù)是在構(gòu)造函數(shù)(constructor)的上下文中定義的。由于它是一個類,創(chuàng)建實(shí)例的唯一方法是使用 new 關(guān)鍵字(省略 new 會拋出錯誤)。

new 關(guān)鍵字會實(shí)例化一個新的對象實(shí)例,并在執(zhí)行構(gòu)造函數(shù)時將 this 指向該實(shí)例。這種行為,加上我們上面已經(jīng)提到的其他行為,就能解釋清楚結(jié)果。

總結(jié)

你做得怎樣?有沒有做對呢?理解了 this 的表現(xiàn)行為,在調(diào)試棘手的問題時能節(jié)省大量時間。如果你做錯了任意一道,那你需要多加練習(xí)。研究上面這些例子,然后回來再做一次,直到你都能做對,并向其他人解釋為什么這些方法會返回這些值。

如果這些題比你想象的要難,你并不是一個人。針對這個主題,我已經(jīng)問過了不少開發(fā)者,我認(rèn)為到目前為止只有一位開發(fā)人員掌握了。

加上類和箭頭函數(shù)的行為,會使 .call(). bind().apply() 的動態(tài)綁定開始變得復(fù)雜。請記住,箭頭函數(shù)總是將 this 綁定在定義時所在的作用域上,第二個例子 class 中的 this 實(shí)際綁定在執(zhí)行構(gòu)造函數(shù)時的作用域上。如果你還有疑問,請記住使用 debugger 工具來驗(yàn)證是否符合你的想法。

還要記住,在JavaScript中,即使不用 this,你也可以做很多事情。根據(jù)我的經(jīng)驗(yàn),幾乎任何東西都可以使用純函數(shù)重新實(shí)現(xiàn),純函數(shù)接收所有傳遞給它們的顯式參數(shù)(你可以將 this 看成是可變的隱式參數(shù))。封裝在純函數(shù)中的邏輯具有確定性,這使得它更易于測試,并且沒有副作用。這意味著與操作 this 不同,你不可能破壞其他任何東西。而每當(dāng)你修改 this 時,依賴于 this 的行為就可能被破壞。

也就是說,this 有時很有用,例如:在大量對象之間共享方法。即使在函數(shù)式編程中,this 對于訪問其他對象上的函數(shù),以實(shí)現(xiàn)在現(xiàn)有函數(shù)之上構(gòu)建新函數(shù)是很有用的,例如:.flatMap() 可以通過組合 this.map()this.constructor.of() 來實(shí)現(xiàn)。

如果你喜歡這篇文章,請關(guān)注我,我會持續(xù)輸出更多原創(chuàng)且高質(zhì)量的內(nèi)容。

原文鏈接:【譯】this 是什么?JavaScript 對象的內(nèi)部工作原理

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/103801.html

相關(guān)文章

  • JavaScript面試問題:事件委托和this

    摘要:主題來自于的典型面試問題列表。有多種方法來處理事件委托。這種方法的缺點(diǎn)是父容器的偵聽器可能需要檢查事件來選擇正確的操作,而元素本身不會是一個監(jiān)聽器。 showImg(http://fw008950-flywheel.netdna-ssl.com/wp-content/uploads/2014/11/Get-Hired-Fast-How-to-Job-Search-Classifieds...

    浠ラ箍 評論0 收藏0
  • JavaScript 工作原理之二-如何在 V8 引擎中書寫最優(yōu)代碼 5 條小技巧()

    摘要:本章將會深入谷歌引擎的內(nèi)部結(jié)構(gòu)。一個引擎可以用標(biāo)準(zhǔn)解釋程序或者即時編譯器來實(shí)現(xiàn),即時編譯器即以某種形式把解釋為字節(jié)碼。引擎的由來引擎是由谷歌開源并以語言編寫。注意到?jīng)]有使用中間字節(jié)碼來表示,這樣就不需要解釋器了。 原文請查閱這里,略有刪減。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第二章。 本章將會深入谷歌 V8 引擎的內(nèi)部結(jié)構(gòu)。我們也會...

    PingCAP 評論0 收藏0
  • []JavaScript如何工作:內(nèi)存管理以及如何處理四種常見內(nèi)存泄漏

    摘要:是如何工作的內(nèi)存管理以及如何處理四種常見的內(nèi)存泄漏原文譯者幾個禮拜之前我們開始一系列對于以及其本質(zhì)工作原理的深入挖掘我們認(rèn)為通過了解的構(gòu)建方式以及它們是如何共同合作的,你就能夠?qū)懗龈玫拇a以及應(yīng)用。 JavaScript是如何工作的:內(nèi)存管理以及如何處理四種常見的內(nèi)存泄漏 原文:How JavaScript works: memory management + how to han...

    tianren124 評論0 收藏0
  • 】理解JavaScript:閉包

    摘要:當(dāng)面試中讓我解釋一下閉包時我懵逼了。這個解釋開始可能有點(diǎn)晦澀,讓我們抽絲剝繭摘下閉包的真面目。此文不詳述作用域有專門的主題闡述,不過作用域是理解閉包原理的基礎(chǔ)。這才是閉包的真正便利之處。閉包使用不當(dāng)就會很坑。 原文鏈接 為什么深度學(xué)習(xí)JavaScript? JavaScript如今是最流行的編程語言之一。它運(yùn)行在瀏覽器、服務(wù)器、移動設(shè)備、桌面應(yīng)用,也可能包括冰箱。無需我舉其他再多不相干...

    岳光 評論0 收藏0
  • JavaScript 工作原理之一-引擎,運(yùn)行時,調(diào)用堆棧()

    摘要:本章會對語言引擎,運(yùn)行時,調(diào)用棧做一個概述。調(diào)用棧只是一個單線程的編程語言,這意味著它只有一個調(diào)用棧。查看如下代碼當(dāng)引擎開始執(zhí)行這段代碼的時候,調(diào)用棧會被清空。之后,產(chǎn)生如下步驟調(diào)用棧中的每個入口被稱為堆棧結(jié)構(gòu)。 原文請查閱這里,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原...

    Betta 評論0 收藏0

發(fā)表評論

0條評論

Hwg

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<