<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 了解 TypeScript **[Peter Vogel](https://msdn.microsoft.com/zh-cn/magazine/ee532098.aspx?sdmr=PeterVogel&sdmi=authors)** 在許多方面,考慮 TypeScript 自身的優點非常有用。TypeScript 語言規范將 TypeScipt 稱為“JavaScript 的語法修飾”。這是事實,并且可能是到達此語言目標受眾(目前使用 JavaScript 的客戶端開發人員)的重要步驟。 您需要先了解 JavaScript,才能了解 TypeScript。事實上,語言規范(請訪問?[bit.ly/1xH1m5B](http://bit.ly/1xH1m5B)?閱讀此文章)通常按照生成的 JavaScript 代碼來描述 TypeScript 構造。但是,將 TypeScript 看作是一種與 JavaScript 共享功能的獨立語言同樣非常有用。 例如,與 C# 一樣,TypeScript 是一種數據類型化的語言,可提供 IntelliSense 支持和編譯時檢查功能等很多功能。與 C# 一樣,TypeScript 包括泛型和 lambda 表達式(或其等效表達式)。 但 TypeScript 當然不是 C#。了解 TypeScript 的獨特功能和了解 TypeScript 與您當前正在使用的服務器端語言所共享的內容同樣重要。TypeScript 類型系統不同于 C#(比 C# 更簡單)。TypeScript 以獨特的方式利用其對其他對象模型的了解,并以不同于 C# 的方式執行繼承。此外,與 C# 不同的是,由于 TypeScript 編譯為 JavaScript,TypeScript 與 JavaScript 共享很多基礎知識。 接下來的問題是,“您愿意用該語言還是用 JavaScript 來編寫客戶端代碼?” ## TypeScript 為數據類型 TypeScript 并沒有很多可用于聲明變量的內置數據類型,只有字符串、數字和布爾。這三種類型都是 any 類型(any 類型在聲明變量時也可以使用)的子類型。您可以針對 null 或未定義的類型來設置或測試通過這四種類型聲明的變量。您還可以將這些方法聲明為 void,來指明他們未返回值。 此示例將一個變量聲明為字符串: ~~~ var name: string; ~~~ 您可以使用枚舉值和四種對象類型來擴展此簡單類型系統:接口、類、數組和函數。例如,以下代碼使用名稱 ICustomerShort 定義了一個接口(一種對象類型)。該接口包含兩個成員:屬性 Id 和方法 CalculateDiscount: ~~~ interface ICustomerShort { ? Id: number; ? CalculateDiscount(): number; } ~~~ 正如在 C# 中一樣,在聲明變量時,您可以使用接口并返回類型。此示例將變量 cs 聲明為類型 ICustomerShort: ~~~ var cs: ICustomerShort; ~~~ 您還可以將對象類型定義為類,類不同于接口,可以包含可執行代碼。此示例使用一個屬性和一個方法定義了 CustomerShort 類: ~~~ class CustomerShort { ? FullName: string; ? UpdateStatus( status: string ): string ? { ??? ...manipulate status...? ??? return status; ? } } ~~~ 類似于 C# 的較新版本,在定義屬性時,不需要提供實現代碼。此名稱和類型的簡單聲明就足夠了。類可以實現一個或多個接口,如**圖 1**?中所示,通過其屬性將我的 ICustomerShort 接口添加到我的 CustomerShort 類。 **圖 1 將接口添加到類** ~~~ class CustomerShort implements ICustomerShort { ? Id: number; ? FullName: string; ? UpdateStatus(status: string): string ? { ??? ...manipulate status... ??? return status; ? } ? CalculateDiscount(): number ? { ??? var discAmount: number; ??? ...calculate discAmount... ??? return discAmount; ? } } ~~~ 如**圖 1**?所示,在 TypeScript 中實現接口的語法與在 C# 中的實現一樣簡單。要實現此接口的成員,您只需添加帶有相同名稱的成員,而無需將接口名稱綁定到相關類成員。在此示例中,我只將 Id 和 CalculateDiscount 添加到了類以實現 ICustomerShort。TypeScript 還允許您使用對象類型文字。此代碼將變量 cst 設置為包含一個屬性和一個方法的對象文字: ~~~ var csl = { ??????????? Age: 61, ??????????? HaveBirthday(): number ????????? { ??????????? return this.Age++; ????????? } ??????? }; ~~~ 此示例使用對象類型指定 UpdateStatus 方法的返回值: ~~~ UpdateStatus( status: string ): { status: string; valid: boolean } { ? return {status: "New", ????????? valid: true ???????? }; } ~~~ 除了對象類型(類、接口、文字和數組)之外,您還可以定義描述函數簽名的函數類型。以下代碼對我的 CustomerShort 類的 CalculateDiscount 進行重寫以接受名為 discountAmount 的單個參數: ~~~ interface ICustomerShort { ? Id: number; ? CalculateDiscount( discountAmount: ??? ( discountClass: string, multipleDiscount: boolean ) => number): number } ~~~ 使用接受兩個參數(一個字符串參數、一個布爾參數)的函數類型對該參數進行定義,并返回一個數字。如果您是 C# 開發人員,您可能會發現此語法看上去像是 lambda 表達式。 實現此接口的類如**圖 2**?所示。 **圖 2 此類實現適當的接口** ~~~ class CustomerShort implements ICustomerShort { ? Id: number; ? FullName: string; ? CalculateDiscount( discountedAmount: ??? ( discountClass: string, multipleDiscounts: boolean ) => number ): number ? { ??? var discAmount: number; ??? ...calculate discAmount... ??? return discAmount; ? } } ~~~ 類似于 C# 的較新版本,TypeScript 還可以從初始化變量的值,推斷出此變量的數據類型。在此示例中,TypeScript 假設變量 myCust 為 CustomerShort: ~~~ var myCust= new CustomerShort(); myCust.FullName = "Peter Vogel"; ~~~ 類似于 C#,您可以使用接口來聲明變量,然后將此變量設置為實現此接口的對象: ~~~ var cs: ICustomerShort; cs = new CustomerShort(); cs.Id = 11; cs.FullName = "Peter Vogel"; ~~~ 最后,您還可以使用類型參數(看起來很像 C# 中的泛型)來使調用代碼指定要使用的數據類型。此示例允許創建類的代碼設置 Id 屬性的數據類型: ~~~ class CustomerTyped<T> { ? Id: T; } ~~~ 此代碼先將 Id 屬性的數據類型設置為字符串,然后才使用它: ~~~ var cst: CustomerTyped<string>; cst = new CustomerTyped<string>(); cst.Id = "A123"; ~~~ 要隔離類、接口和其他公共成員并避免名稱沖突,您可以在與 C# 命名空間類似的模塊中聲明這些構造。您必須使用導出關鍵字標記這些您希望提供給其他模塊使用的項。**圖 3**?中的模塊導出兩個接口和一個類。 **圖 3 導出兩個接口和一個類** ~~~ module TypeScriptSample { ? export interface ICustomerDTO ? { ??? Id: number; ? } ? export interface ICustomerShort extends ICustomerDTO ? { ??? FullName: string; ? } ? export class CustomerShort implements ICustomerShort ? { ??? Id: number; ??? FullName: string; ? } ~~~ 要使用導出的組件,您可以使用模塊名稱作為此組件名稱的前綴,如以下示例中所示: ~~~ var cs: TypeScriptSample.CustomerShort; ~~~ 或者,您可以使用 TypeScript 導入關鍵字來建立此模塊的快捷方式: ~~~ import tss = TypeScriptSample; ... var cs:tss.CustomerShort; ~~~ ## TypeScript 在數據類型化方面非常靈活 如果您是 C# 程序員,除了可能的變量聲明反轉(變量名稱在前,數據類型在后)和對象文字之外,您對這一切應該非常熟悉。然而,TypeScript 中幾乎所有數據類型化都是可選的。此規范將數據類型描述為“注釋”。如果您省略數據類型(并且 TypeScript 無法推斷出此數據類型),則數據類型默認為 any 類型。 TypeScript 也不要求數據類型嚴格匹配。TypeScript 使用規范稱為“結構子類型化”的功能來確定兼容性。這與通常稱為“鴨子類型化”的功能類似。在 TypeScript 中,如果兩個類擁有具有相同類型的成員,就將他們視為相同。例如,以下是一個實現 ICustomerShort 接口的 Customer-Short 類: ~~~ interface ICustomerShort { ? Id: number; ? FullName: string; } class CustomerShort implements ICustomerShort { ? Id: number; ? FullName: string; } ~~~ 以下是一個與我的 CustomerShort 類相似的 CustomerDeviant 類: ~~~ class CustomerDeviant { ? Id: number; ? FullName: string; } ~~~ 借助結構子類型化,我可以使用帶有使用我的 CustomerShort 類或 ICustomerShort 接口定義的變量的 CustomerDevient。這些示例將 CustomerDeviant 與聲明為 CustomerShort 或 ICustomerShort 的變量互換使用: ~~~ var cs: CustomerShort; cs = new CustomerDeviant cs.Id = 11; var csi: ICustomerShort; csi = new CustomerDeviant csi.FullName = "Peter Vogel"; ~~~ 這種靈活性使您可以將 TypeScript 對象文字分配給聲明為類或接口的變量,假設它們在結構上兼容,如以下示例所示: ~~~ var cs: CustomerShort; cs = {Id: 2, ????? FullName: "Peter Vogel" ???? } var csi: ICustomerShort; csi = {Id: 2, ?????? FullName: "Peter Vogel" ????? } ~~~ 這會引入導致可分配性常見問題的有關明顯類型、父類型和子類型的 TypeScript 特定功能,本文將跳過這部分內容。例如,這些功能將允許 CustomerDeviant 擁有 CustomerShort 中不存在的成員,而不會導致我的示例代碼失敗。 ## TypeScript 擁有類 TypeScript 規范將此語言稱作實現“在面向對象的繼承機制上[使用]原型鏈來實現許多變體的類模式”。實際上,這意味著 TypeScript 不只是數據類型化,而是高效地面向對象的。 與 C# 接口可以從基接口進行繼承一樣,TypeScript 接口也可以采用相同的方式擴展另一個接口,即使另一個接口是在其他模塊中定義的。此示例擴展了 ICustomerShort 接口并創建了名為 ICustomerLong 的新接口: ~~~ interface ICustomerShort { ? Id: number; } interface ICustomerLong extends ICustomerShort { ? FullName: string; } ~~~ ICustomerLong 接口將擁有兩個成員:FullName 和 Id。在合并的接口中,先顯示來自此接口的成員。因此,我的 ICustomerLong 接口相當于此接口: ~~~ interface ICustomerLongPseudo { ? FullName: string; ? Id: number; } ~~~ 實現 ICustomerLong 的類將需要這兩個屬性: ~~~ class CustomerLong implements ICustomerLong { ? Id: number; ? FullName: string; } ~~~ 類可以用接口擴展另一個接口的方式來擴展其他類。**圖 4**?中的類擴展了 CustomerShort,并將新屬性添加到定義中。它使用顯式 getter 和 setter 來定義屬性(盡管這不是一個特別有用的方法)。 **圖 4 使用 getter 和 setter 定義的屬性** ~~~ class CustomerShort { ? Id: number; } class CustomerLong extends CustomerLong { ? private id: number; ? private fullName: string; ? get Id(): number ? { ??? return this.id ? } ? set Id( value: number ) ? { ??? this.id = value; ? } ? get FullName(): string ? { ??? return this.fullName; ? } ? set FullName( value: string ) ? { ??? this.fullName = value; ? } } ~~~ TypeScript 采用通過引用此類 (this) 訪問內部字段(如 id 和 fullName)的最佳做法。這些類還可以具有包含 C# 剛采用的功能的構造函數:自動定義字段。TypeScript 類中的構造函數必須命名為構造函數,其公共參數會自動定義為屬性,并從傳遞給這些屬性的值進行初始化。在此示例中,構造函數將接受字符串類型的名為 Company 的單個參數: ~~~ export class CustomerShort implements ICustomerShort { ? constructor(public Company: string) ? {?????? } ~~~ 由于 Company 參數定義為公共,此類還獲取一個從傳遞給構造函數的值初始化而來的名為 Company 的公共屬性。借助該功能,變量 comp 將設置為“PH&VIS”,如該示例所示: ~~~ var css: CustomerShort; css = new CustomerShort( "PH&VIS" ); var comp = css.Company; ~~~ 將構造函數的參數聲明為私有會創建一個內部屬性,此內部屬性只能通過關鍵字 this 從類成員內部的代碼進行訪問。如果此參數沒有聲明為公共或私有,則不會生成屬性。 您的類必須擁有一個構造函數。正如在 C# 中一樣,如果您未提供一個構造函數,系統將向您提供一個。如果您的類擴展了其他類,則您創建的任何構造函數必須包含對 super 的調用。將調用正在擴展的類上的構造函數。此示例包括帶有 super 調用的構造函數,該調用向基類的構造函數提供參數: ~~~ class MyBaseClass { ? constructor(public x: number, public y: number ) { }??? } class MyDerivedClass extends MyBaseClass { ? constructor() ? { ??? super(2,1); ? } } ~~~ ## TypeScript 以不同的方式繼承 同樣,如果您是 C# 程序員,除了一些有趣的關鍵字 (extends) 之外,您對這一切都會感到熟悉。但是同樣,擴展類或接口與 C# 中的繼承機制并不完全相同。TypeScript 規范針對被擴展的類(“基類”)和擴展它的類(“派生類”)使用常規術語。但是,例如,此規范將一個類稱為“遺產規范”,而沒有使用單詞“繼承”。 首先,在定義基類時,TypeScript 的選項要少于 C# 的選項。您無法將類或成員聲明為不能替代的、抽象的或虛擬的(盡管接口提供了很多虛擬基類所提供的功能)。 無法防止一些成員不能被繼承。派生類繼承基類的所有成員,包括公共和私有成員(基類的所有公共成員都可替代,而私有成員都不可替代)。要替代公共成員,只需在派生類中使用相同簽名定義一個成員。雖然您可以使用 super 關鍵字來從派生類訪問公共方法,但無法使用 super 訪問基類中的屬性(盡管您可以替代此屬性)。 TypeScript 允許您通過簡單地使用相同名稱和新成員聲明接口來增加一個接口。這允許您擴展現有 JavaScript 代碼,而無需創建新的命名類型。**圖 5**?中的示例通過兩個單獨的接口定義來定義 ICustomerMerge 接口,然后在類中實現該接口。 **圖 5 通過兩個接口定義來定義的 ICustomerMerge 接口** ~~~ interface ICustomerMerge { ? MiddleName: string; } interface ICustomerMerge { ? Id: number; } class CustomerMerge implements ICustomerMerge { ? Id: number; ? MiddleName: string; } ~~~ 這些類還可以擴展其他類,但不能擴展接口。在 TypeScript 中,接口也可以擴展類,但只能以涉及繼承的方式實現。當接口擴展類時,接口包括所有類成員(公共和私有),但不包括此類的實現。在**圖 6**?中,ICustomer 接口將擁有私有成員 id、公共成員 Id 以及公共成員 MiddleName。 **圖 6 帶有所有成員的擴展類** ~~~ class Customer { ? private id: number; ? get Id(): number ? { ??? return this.id ? } ? set Id( value: number ) ? { ??? this.id = value; ? } } interface ICustomer extends Customer { ? MiddleName: string; } ~~~ ICustomer 接口具有很大的限制,您只能將其與擴展該接口所擴展的類(在本示例中,為 Customer 類)的類結合使用。TypeScript 需要您在要從此接口擴展的類上繼承的接口中(而不是在派生類中重新實現的接口上)包括私有成員。例如,使用 ICustomer 接口的新類需要為 MiddleName 提供一個實現(因為 MiddleName 只在此接口中指定)。使用 ICustomer 的開發人員可以選擇從 Customer 類繼承或替代公共方法,但無法替代私有 id 成員。 此示例展示了根據需要實現 ICustomer 接口并擴展 Customer 類的類(稱為 NewCustomer)。在本示例中,NewCustomer 從 Customer 繼承 Id 的實現,并為 MiddleName 提供一個實現: ~~~ class NewCustomer extends Customer implements ICustomer { ? MiddleName: string; } ~~~ 這一接口、類、實現和擴展的組合為您進行定義用于擴展在其他對象模型中定義的類的類提供了一種受控的方式(有關詳細信息,請查看語言規范 7.3 部分,“擴展類的接口”)。再加上 TypeScript 使用其他 JavaScript 庫相關信息的能力,TypeScript 可以讓您編寫與在那些庫中定義的對象配合使用的 TypeScript 代碼。 ## TypeScript 了解您的庫 除了了解在您的應用程序中定義的類和接口,您可以向 TypeScript 提供有關其他對象庫的信息。可以通過 TypeScript 聲明關鍵字進行處理。這就創建了規范所指的“環境聲明”。您可能從來不需要親自使用聲明關鍵字,因為您可以在 DefinitelyTyped 站點 ([definitelytyped.org](http://definitelytyped.org/)) 上找到大多數 JavaScript 庫的定義文件。通過這些定義文件,TypeScript 可以高效地“閱讀有關您需使用的庫的文檔”。 當然,在使用構成該庫的對象時,“閱讀文檔”意味著您將獲取數據類型化的 IntelliSense 支持和編譯時檢查。在某些情況下,這還允許 TypeScript 從使用變量的上下文中推斷出變量的類型。借助于隨 TypeScript 提供的 lib.d.ts 定義文件,TypeScript 假設在以下代碼中變量定位標記的類型為 HTMLAnchorElement: ~~~ var anchor = document.createElement( "a" ); ~~~ 當 createElement 方法傳遞字符串“a”時,此定義文件指定這就是由此方法所返回的結果。例如,知道定位標記是 HTMLAnchorElement,意味著 TypeScript 知道定位標記變量將支持 addEventListener 方法。 TypeScript 數據類型接口還適用于參數類型。例如,addEventListener 方法接受兩個參數。第二個為函數,addEventListener 在其中傳遞了類型 PointerEvent 的對象。TypeScript 知道這一點,并支持訪問此函數中 PointerEvent 類的 cancelBubble 屬性: ~~~ span.addEventListener("pointerenter", function ( e ) { ? e.cancelBubble = true; } ~~~ 其他 JavaScript 的定義文件以 lib.d.ts 提供 HTML DOM 相關信息的方式提供類似的功能。例如,在將 backbone.d.ts 文件添加到我的項目之后,我可以聲明一個類,該類擴展了 Backbone Model 類并通過如下代碼實現了我的接口: ~~~ class CustomerShort extends bb.Model implements ICustomerShort { } ~~~ 如果您對如何將 TypeScript 與 Backbone、Knockout 結合使用的詳細信息感興趣,請查閱我的實用 TypeScript 專欄 ([bit.ly/1BRh8NJ](http://bit.ly/1BRh8NJ))。在新的一年中,我將詳細研究如何將 TypeScript 與 Angular 結合使用。 TypeScript 的功能遠不止此。TypeScript 版本 1.3 將來必定包括 union 數據類型(例如,以便支持返回特定類型列表的函數)和聚合。TypeScript 團隊正在與將數據類型化應用于 JavaScript(Flow 和 Angular)的其他團隊合作,以確保 TypeScript 可以與盡可能多的 JavaScript 庫結合使用。 如果您需要執行 JavaScript 支持而 TypeScript 不允許的操作,則可以始終集成您的 JavaScript 代碼,因為 TypeScript 是 JavaScript 的超集。因此,接下來的問題是,您更喜歡使用哪種語言來編寫客戶端代碼?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看