摘要:靜態(tài)屬性靜態(tài)方法目前支持靜態(tài)方法表示,類屬性及靜態(tài)屬性目前作為提案還未正式成為標(biāo)準(zhǔn)。在中,抽象類不能用來實(shí)例化對象,主要做為其它派生類的基類使用。不同于接口,抽象類可以包含成員的實(shí)現(xiàn)細(xì)節(jié)。中也是這樣規(guī)定的抽象類不允許直接被實(shí)例化。
嘗試重寫
在此之前,通過《JavaScript => TypeScript 入門》已經(jīng)掌握了類型聲明的寫法。原以為憑著那一條無往不利的規(guī)則,就可以開開心心的重寫 JS 項(xiàng)目了。當(dāng)我躍躍欲試去重寫一個(gè) JS 項(xiàng)目時(shí),發(fā)現(xiàn)阻礙重重。
在投靠 TS 時(shí),TypeScript 允許將 JS 漸進(jìn)式的過渡到 TS:
一些簡單的基本類型聲明的填充,比如:number, :string, :string[] 等等;
將一些稍復(fù)雜的、暫時(shí)還未提煉好的結(jié)構(gòu)聲明為 any 類型;
改后綴為 .ts, 執(zhí)行 tsc 編譯。
但一個(gè)明顯的問題是,一個(gè) JS 文件中往往有很多模塊依賴,意味著要把所有這些模塊都重新做一次類型聲明,才能整體編譯通過。
所以,要想暢通無阻的重寫 JS,在上一篇入門的基礎(chǔ)上,還得強(qiáng)忍著沖動(dòng),繼續(xù)學(xué)習(xí)兩部分內(nèi)容:
1、TS 類的寫法、特征
2、TS 模塊、命名空間
好在,它們和 ES6 其實(shí)有著很多重合的地方——要記得,TS 是 ES6 的超集。所以如果掌握了 ES6,我們只要挑差異,找增量,進(jìn)行遷移學(xué)習(xí),就能快速掌握上述內(nèi)容。
ES6 的類ES6 的類的概念,和普遍編程語言的類概念一致,表示一種特有的數(shù)據(jù)結(jié)構(gòu)。它既像一個(gè)函數(shù)(能被 new 調(diào)用),又像一個(gè)對象(包含了各種屬性、方法)。
class MyClass { constructor() { this.attr = "my attribute"; } foo(name) { console.log("hello " + name); } } let myclass = new MyClass();
類中的方法屬性被稱為 “成員”,這些成員大概被分成 3 種類別:
公有屬性、公有方法
私有屬性、私有方法
靜態(tài)屬性、靜態(tài)方法
在寫繼承時(shí),我們并不希望在所有時(shí)候,這些屬性、方法都被繼承到子類;在訪問成員時(shí),也不希望在任何時(shí)候,類實(shí)例的所有成員都無一例外可以被訪問;有時(shí)候我們希望與此相反,這樣能保持開放出去的信息簡潔干凈。
JS 很早就有這些概念,但到現(xiàn)在為止,ES6 并沒有處理好這個(gè)事情。
私有屬性、私有方法ES6 沒有直觀的表示私有屬性、私有方法的方案,只能通過變通的方式間接地表示。
const getKeys = Symbol("getKeys_"); const attr = Symbol("attr_"); class MyClass { constructor() { // 私有屬性 this[attr] = "private attribute"; } // 公有方法 foo(config) { return this[fn](config); } // 私有方法 [getKeys](config) { return Object.keys(config); } };
這僅僅是一個(gè)間接取巧的方式避免直接被訪問到,但很輕易就能繞過它:
let myclass = new MyClass(); let symbolsAttr = Object.getOwnPropertySymbols(myclass); let attr_ = myclass[symbolsAttr[0]]; // 即訪問到私有屬性 let symbolsFn = Object.getOwnPropertySymbols(myclass.__proto__); let getKeys_ = myclass[symbolsFn[0]]; // 即訪問到私有方法
私有方法、私有屬性的目的是不想開放過多的信息到外部。上面變通的方案雖然表面上達(dá)到了目的,但是不夠直觀,也不安全。
靜態(tài)屬性、靜態(tài)方法ES6 目前支持靜態(tài)方法表示,類屬性及靜態(tài)屬性目前作為提案還未正式成為標(biāo)準(zhǔn)。
class MyClass { name = "jeremy"; // ES6 不被支持,僅作為提案 static version = "1.0.0"; // ES6 不被支持,僅作為提案 constructor() { console.log(MyClass.version); // "1.0.0" } static get Version() { return MyClass.version; } }
區(qū)分這些成員身份,與動(dòng)態(tài)類型、靜態(tài)類型語言沒有必然聯(lián)系,可以預(yù)見,在不久的將來,ES6 這方面將得到完善。
TS 的類鑒于 TS 是 ES6 的超集這一事實(shí),TS 類當(dāng)然也有私有屬性、私有方法,靜態(tài)屬性、靜態(tài)方法等這些身份的成員。在標(biāo)記成員身份上,TS 與 Java 有很多相似之處。比如與繼承相關(guān)的訪問修飾符,以及其他限定作用的非訪問修飾符。
訪問修飾符
private
public
protected
非訪問修飾符
static
readonly
abstract
class User { readonly name: string; public age: number; private sex: string; protected marriage: string; constructor(name: string, sex: string) { this.name = name; this.sex = sex; } showAge() { console.log(`${this.name}, age ${this.age}`); } }訪問修飾符
1、當(dāng)成員被標(biāo)記成 private 時(shí),它就不能在聲明它的類的外部訪問。
2、protected 修飾符與 private 修飾符的行為很相似,但有一點(diǎn)不同,protected 成員在派生類中仍然可以訪問
3、被聲明為 public 的類、方法、構(gòu)造方法和接口能夠被任何其他類訪問。
class User { readonly name: string; public age: number; private sex: string; protected marriage: string; constructor(name: string, sex: string) { this.name = name; this.sex = sex; } showAge() { console.log(this.age); } } let a = new User("jerry", "male"); console.log(a.sex); // 編譯報(bào)錯(cuò):私有屬性不許在本類之外被訪問 console.log(a.marriage); // 編譯報(bào)錯(cuò):私有屬性不許在類之外被訪問 a.name = "jeremy"; // 編譯報(bào)錯(cuò):只讀屬性不許再次被寫入
訪問修飾符主要用在繼承的可訪問性上,繼承好比遺傳,用基因類比理解它們就很有意思:
private 私有基因——本體有效,不會(huì)被繼承,即子類中無法訪問到
protected 被保護(hù)基因——保護(hù)血統(tǒng)純正,只允許在繼承體系中訪問
public 公共基因——子類、其他類都能訪問到
有了訪問修飾符,每個(gè)成員都有扮演著與身份對應(yīng)的角色,真正做到名副其實(shí)。
訪問修飾符和非訪問修飾符加起來有6個(gè)甚至更多,它們?nèi)绾闻c類、接口一起搭配工作,考慮到組合情況非常多,此處不去細(xì)致的探究。可以參考 Java 的規(guī)則:
default (即缺省,什么也不寫): 在同一包(等同于JS中的模塊)內(nèi)可見,不使用任何修飾符。使用對象:類、接口、變量、方法。
private : 在同一類內(nèi)可見。使用對象:變量、方法。 注意:不能修飾類(外部類)
public : 對所有類可見。使用對象:類、接口、變量、方法
protected : 對同一包內(nèi)的類和所有子類可見。使用對象:變量、方法。 注意:不能修飾類(外部類)。
當(dāng)然更直觀的方式是上代碼 + 編譯。TS 的編譯工具有著非常友好、明確編譯錯(cuò)誤提示。
class Demo { static private showSelf() {} } // 編譯錯(cuò)誤提示 error TS1029: "private" modifier must precede "static" modifier.
當(dāng)然,去查閱官方文檔也是一個(gè)好辦法。
非訪問修飾符非訪問修飾符不關(guān)心可訪問性,被它多帶帶標(biāo)記的成員,在任何時(shí)候都能訪問到。目前至少有這些:
static
get
set
readonly
abstract
從字面上看,不難理解它們的用途。這里和 ES6 差別較大的是 abstract。
abstract 修飾符abstract 修飾符用來定義抽象類和在抽象類內(nèi)部定義抽象方法。
在 Java 中,抽象類不能用來實(shí)例化對象,主要做為其它派生類的基類使用。 不同于接口,抽象類可以包含成員的實(shí)現(xiàn)細(xì)節(jié)。
TS 中也是這樣規(guī)定的:抽象類不允許直接被實(shí)例化。
還有一點(diǎn)很重要,抽象類中的抽象方法可以不包含具體實(shí)現(xiàn),但必須在派生類中實(shí)現(xiàn)。
// 抽象類 abstract class User { readonly name: string; public age: number; private sex: string; protected marriage: string; constructor(name: string, sex: string) { this.name = name; this.sex = sex; } showAge() { console.log(this.age); } // 抽象方法 abstract showName(): void; } // let a = new User("jerry", "male"); // 編譯報(bào)錯(cuò): 抽象類不允許直接實(shí)例化
容易忽略的一個(gè)問題是,一個(gè)類中一旦出現(xiàn)抽象方法,那這個(gè)類整個(gè)應(yīng)該被標(biāo)記為 abstract。
class UserA extends User { constructor(name: string, sex: string) { super(name, sex); // console.log(this.sex); // 編譯報(bào)錯(cuò):私有變量不能被訪問 } // 抽象方法必須要在子類中實(shí)現(xiàn) // 若無此方法,編譯報(bào)錯(cuò) showName() { console.log(this.name); } }
基本上,對 TS 類只需要掌握這些,深入的部分自然在實(shí)踐中繼續(xù)領(lǐng)悟。
對了,還有模塊、命名空間沒有梳理。因?yàn)榇a文字的麻煩,只得留到后續(xù)再補(bǔ)。但是直接搬用 ES6 的模塊import, export 就完全夠用了。
So,這回真的去重寫了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/89951.html
摘要:為了由簡入繁,不妨將這些類型劃分為基本類型復(fù)合類型。以下將漸進(jìn)式的對的這些類型進(jìn)行了解。實(shí)際上,有一種屬性描述對象,是通過獲取的。但無論如何,類型檢查是可以排除大部分錯(cuò)誤的。在函數(shù)的類型聲明中,繼續(xù)來鞏固這條規(guī)則的寫法。 幾個(gè)月前把 ES6 的特性都過了一遍,收獲頗豐?,F(xiàn)在繼續(xù)來看看 TypesScript(下文簡稱為 TS)。限于經(jīng)驗(yàn),本文一些總結(jié)如有不當(dāng),歡迎指正。 概述 官網(wǎng)有這...
摘要:前言這個(gè)輪子已經(jīng)有很多人造過了,為了不重復(fù)造輪子,我將本項(xiàng)目以三階段實(shí)現(xiàn)大家可以在中的查看純前端后端前端后端前端希望能給大家一個(gè)漸進(jìn)學(xué)習(xí)的經(jīng)驗(yàn)。 前言 Vue+Socket.io這個(gè)輪子已經(jīng)有很多人造過了,為了不重復(fù)造輪子,我將本項(xiàng)目以三階段實(shí)現(xiàn)(大家可以在github中的Releases查看): 純前端(Vuex) 后端+前端(JavaScript) 后端+前端(TypeScrip...
摘要:添加了可選的靜態(tài)類型注意并不是強(qiáng)類型和基于類的面向?qū)ο缶幊?。類類型接口示例接口更注重功能的設(shè)計(jì),抽象類更注重結(jié)構(gòu)內(nèi)容的體現(xiàn)模塊中引入了模塊的概念,在中也支持模塊的使用。 一:Typescript簡介 維基百科: TypeScript是一種由微軟開發(fā)的自由和開源的編程語言。它是JavaScript的一個(gè)嚴(yán)格超集,并添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊?。C#的首席架構(gòu)師以及Delp...
摘要:現(xiàn)在,出現(xiàn)了更多本身支持或者通過插件支持語法智能提示糾錯(cuò)甚至是內(nèi)置編譯器的文本編輯器和。 TypeScript是什么 TypeScript是JavaScript的一個(gè)超集 TypeScript需要編譯為JavaScript才能運(yùn)行(語法糖) TypeScript提供了類型系統(tǒng),規(guī)范類似Java TypeScript提供了ES6的支持,也可以支持部分ES7草案的特性,不用擔(dān)心TypeS...
摘要:入門,第一個(gè)這是一門很新的語言,年前后正式公布,算起來是比較年輕的編程語言了,更重要的是它是面向程序員的函數(shù)式編程語言,它的代碼運(yùn)行在之上。它通過編輯類工具,帶來了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經(jīng)到來了,總結(jié)過去的 2017,相信小伙們一定有很多收獲...
閱讀 3721·2021-11-23 09:51
閱讀 1384·2021-11-10 14:35
閱讀 4022·2021-09-22 15:01
閱讀 1292·2021-08-19 11:12
閱讀 392·2019-08-30 15:53
閱讀 1702·2019-08-29 13:04
閱讀 3439·2019-08-29 12:52
閱讀 3069·2019-08-23 16:14