摘要:今天看到寫的中的和都錯了,覺得很有意思,所以也研究了一下。但既然用,就是為了用它的靜態檢查,所以要充分關注編譯錯誤提示。很遺憾,同樣的錯誤。的正式名稱是,即那么,現在來說說的結果。因此在我實際工作中遇到類似問題的概率非常低,不糾結
今天看到 @justjavac 寫的《ES6 中的 this & super:babel 和 typescript 都錯了》,覺得很有意思,所以也研究了一下。
借用 @justjavac 的示例代碼,略做修改,然后在幾種語言中跑了一下,結果
語言(版本) | 輸出1 | 輸出2 | 輸出3 |
---|---|---|---|
ES6 | 3 | undefined | 3 |
Babel | 2 | undefined | 2 |
TypeScript (?) | 2 | 3 | 2 |
C# | 3 | 3 | 3 |
Java | 3 | 3 | 3 |
是的,我加入了 C# 和 Java 的運行結果,畢竟它們是真正的 OOP 語言。另外請注意到,我在 TypeScript 后面加了個問號 (?),因為實際上 TypeScript 雖然編譯成了對應的 JS,但是轉譯過程中是會報錯的:
index.ts (20,15): Only public and protected methods of the base class are accessible via the "super" keyword. (2340) index.ts (22,27): Only public and protected methods of the base class are accessible via the "super" keyword. (2340)
下面,我從 C#/Java 說起
C# / Java對于 C#/Java 這樣的真正的 OOP 語言來說,super.x 和 this.x 其實是一個東西,因為在子類中沒有重新定義這個成員 x。以 C# 代碼為例
using System; public class Program { public static void Main() { var t = new ColorPoint(); t.test(); } } class Point { public int x; protected void getValue() { Console.WriteLine(this.x); } } class ColorPoint : Point { public ColorPoint() { this.x = 2; base.x = 3; Console.WriteLine(this.x); Console.WriteLine(base.x); } public void test() { this.getValue(); } }
上面這段代碼是為了與下面這段代碼進行比較——假如我們在子類中重新定義 x 呢?
class ColorPoint : Point { public new int x; public ColorPoint() { this.x = 2; base.x = 3; Console.WriteLine(this.x); Console.WriteLine(base.x); } public void test() { this.getValue(); } }
它的輸出是 2、3、3,為什么?
this.x 是 2 好理解,super.x 是 3 也好理解。而 getValue() 中實際取的是父類中的 x,似乎有點不好理解——
其實也不難理解,因為子類中重新定義了 x,它和父類中的 x 就不是同一個東西了,只是正好名稱相同而已。
另一個方面來理解:子類中重新定義 x,而不是重載(也不可能重載字段,只有方法和屬性可以重載),那么 getValue() 就不會順著虛函數鏈去找到最近的一個定義,也就不會取到子類中的賦值。
TypeScript在 TypeScript 的 Playground 中運行下面的代碼確實可以得到 2、3、2:
class Point { public x: number; protected getValue() { console.log(this.x); } } class ColorPoint extends Point { constructor() { super(); this.x = 2; super.x = 3; console.log(this.x); console.log(super.x); } test() { this.getValue(); } } const t = new ColorPoint(); t.test();
問題在于,不管是在 Playground 還是 VSCode 還是 vsc(編譯器),都會得到錯誤提示
Only public and protected methods of the base class are accessible via the "super" keyword.
這里提到了用 super 的兩個條件,一個是 public 或 protected 修飾,二個是 methods。第二個條件就是關鍵所在:TypeScript 中只能通過 super 調用方法,所以 super.x 從語法上來說就是錯的!我不知道 Anders Hejlsberg 為什么要在語法錯誤的情況仍然輸出結果——也許是為了容錯性。但既然用 TypeScript,就是為了用它的靜態檢查,所以要充分關注編譯錯誤提示。
現在來試驗一下介于 field 和 method 之間的情況,使用 getter/setter 語法的屬性。
class Point { private _x: number; public get x(): number { return this._x; } public set x(value: number) { this._x = value; } protected getValue() { console.log(this.x); } }
很遺憾,同樣的錯誤。就這一點來說,我覺得 TypeScript 還有待進步。
ES6 / ES2015 / BabelES6 的正式名稱是 ECMAScrip 2015,即 ES2015
那么,現在來說說 ES6 的結果 3、undefined、3。
……
可是,我除了說不能理解之外,還能說什么呢?
既然 super.x = 3 都可以起作用,憑什么 console.log(super.x) 就取不到值?從這一點上來說,Babel 的結果 (2、undefined、2) 反而更符合邏輯。
小結ES6 的結果我不能理解,也許能從 ECMAScript 2015 Language Specification 中找到答案,不過我沒耐心去閱讀這個長而枯燥的英文文檔——如果有人找到了答案,麻煩告訴我一聲,萬分感謝!
不管怎么說,我用 TypeScript 的時間比較多,而且忠實于編譯器的錯誤提示。因此在我實際工作中遇到類似問題的概率非常低,不糾結 ^_^!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88281.html
摘要:工具軟件欲先攻其事必先利其器,用好工具是做好開發的基礎。框架目前最流行簡單易用,越來越多人用曾經很流行,現在有點衰退狀態管理后端渲染開發工具依賴管理,應用打包,任務管理,編輯器擴展,,移動端有了前端的知識后,我們還可以開發手機。 2019年即將到來,各位同學2018年辛苦了。 不管大家2018年過的怎么樣,2019年還是要繼續加油的! 在此我整理了個人認為在2019仍是或者將成為主流的...
摘要:是的超級,遵循最新的規范相當于包含了的語法。表示方法沒有返回任何類型類型表示的是那些永不存在的值的類型,例如異常錯誤寫法錯誤三函數內容概述函數的定義可選參數默認參數剩余參數函數重載箭頭函數。 一、Typescript 介紹、環境搭建 1.1 Typescript 介紹 1.TypeScript 是由微軟開發的一款開源的編程語言,像后端 java、C#這樣的面向對象語言可以讓 js 開發...
摘要:當你陷在一個中大型項目中時應用日趨成為常態,沒有類型約束類型推斷,總有種牽一發而動全身的危機和束縛。總體而言,這些付出相對于代碼的健壯性和可維護性,都是值得的。目前主流的都為的開發提供了良好的支持,比如和。參考資料中文文檔 文章博客地址:http://pinggod.com/2016/Typescript/ TypeScript 是 JavaScript 的超集,為 JavaScrip...
摘要:不過,相對于靜態類型檢查帶來的好處,這些代價是值得的。當然少不了的模塊化標準,雖然到目前為止和大部分瀏覽器都還不支持它。本身支持兩種模塊化方式,一種是對的模塊的微小擴展,另一種是在發布之前本身模仿的命名空間。有一種情況例外。 TypeScript 帶來的最大好處就是靜態類型檢查,所以在從 JavaScript 轉向 TypeScript 之前,一定要認識到添加類型定義會帶來額外的工作量...
摘要:將轉換成常見的使用實現的基于迭代器的迭代。處停止迭代器基于鴨子模型接口這里使用語法僅僅為了說明問題使用支持為了使用迭代器屬性需要引入。生成器是迭代器的子類,包含了附加的與。 原文地址:http://babeljs.io/docs/learn-...本文基于Luke Hoban精妙的文章《es6features》,請把star獻給他,你可以在此嘗試這些特性REPL。 概述 ECMAScr...
閱讀 1818·2023-04-26 02:51
閱讀 2849·2021-09-10 10:50
閱讀 3026·2021-09-01 10:48
閱讀 3594·2019-08-30 15:53
閱讀 1816·2019-08-29 18:40
閱讀 405·2019-08-29 16:16
閱讀 2024·2019-08-29 13:21
閱讀 1816·2019-08-29 11:07