亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

深入理解JavaScript和TypeScript中的class

2024-05-06 16:43:52
字體:
來源:轉載
供稿:網友

前言

對于一個前端開發者來說,很少用到 class ,因為在 JavaScript 中更多的是 函數式 編程,抬手就是一個 function,幾乎不見 class 或 new 的蹤影。所以 設計模式 也是大多數前端開發者的一個短板。

最近在學習 Angular 的過程中發現其大量的運用了 class,不得不佩服,Angular 確實是一個優秀的、值得深入研究的 框架。

本文將簡單的介紹一下 JavaScript 和 TypeScript 中的 class。

基本概念

在介紹 class 之前,要先介紹一些基本的概念。

1、靜態成員

類自身的成員,可以繼承,但實例無法訪問,一般多見于工具類,比如在jQuery時代最常見的 $.ajax ,ajax 便是 $ 的靜態方法,使用方便,不需要再通過 new 或者函數調用的得到一個新實例。

2、私有成員

類內部的成員,一般是不能繼承的,只能在內部使用,實例無法訪問,有一點點像閉包內部的變量,但是還是一定的差別,目前 JavaScript 無法直接定義私有成員,只能通過其它方式輔助實現。

3、getter/setter

存取器屬性,當我們訪問或者修改一個實例的屬性的時候,我們可通過存取器屬性攔截這兩個操作,從而做一些其它的事情,vue正是通過這個api來實現對數據變化的追蹤。

4、實例成員

指 new 出來的實例所具有的成員,可以被繼承,也是通過這個特性實現了代碼的復用。

5、抽象類,抽象方法

抽象類指不可以被實例化的類,通過 new 關鍵字調用會報錯,一般都被設計成父類。

抽象方法,只提供方法的名稱,參數和返回值,不負責實現,具體的實現由子類去完成,如果一個子類繼承于抽象類,那么這個子類必須實現父類所有的抽象方法,否則會報錯。

這兩個概念在 JavaScript 都無法直接實現,但在 TypeScript 或 其它面向對象語言中可以輕松實現,另外這個特性也是用于實現 多態 的重要手段。

案例介紹

為了更好的介紹 class,本文將采用三個 類 來做例子,分別是 Person、Chinese、American。從字面上可以很快的知道: Person 是 父類(基類) ,Chinese 和 American 是 子類(派生類) 。

Person 有 name、age、gender 三個屬性,sayHello 方法和 fullName 存取器屬性。同時 Person 還有一些 靜態成員 和 私有成員 ,由于實在太難想例子了,所以就用 foo、bar、x、y、z 這些來代替吧。

作為子類的 Chinese 和 American 繼承了 Person 的實例成員和靜態成員。同時它們自身也有一些自己的方法和屬性:

Chinese 有 kungfu 屬性,會習武 martial。

American 有 twitter,還可以 sendTwitter。

接下來我們就分別使用 JavaScript 和 TypeScript 來實現這個案例。

JavaScript 中的 class

JavaScript 中的 class 要分開說,在 ES6 中提供了兩個關鍵字 class 和 extends ,雖然它們只是語法糖,底層還是再利用 prototype 實現繼承的,但是不能否認,這中寫法確實讓代碼更清晰,更易讀。

ES6 中的 class

class Person { // #x = '私有屬性x'; // static x = '靜態屬性x'; // name; // age; // gender; // 上面的寫法還在提案中,并沒有成為正式標準,不過變化的可能性已經不大了。 // 順便吐槽一下,用 # 表示私有成員,真的是很無語. /**  * Person的靜態方法,可以被子類繼承  * 可以通過 this 訪問靜態成員  */ static foo() {  console.log(`類 ${this.name} 有一個 ${this.x}`); } constructor(name, age, gender) {  this.name = name;  this.age = age;  this.gender = gender; } /**  * 數據存儲器,可以訪問實例成員,子類的實例可以繼承  * 以通過 this 訪問實例成員  */ get fullName() {  const suffix = this.gender === '男' ? '先生' : '女士';  return this.name + suffix; } set fullName(value) {  console.log(`你已改名為 ${value} `); } /**  * Person的實例方法,可以被子類的實例繼承  * 可以通過 this 訪問實例成員  */ sayHello() {  console.log(`你好我是 ${this.fullName} ,我 ${this.age} 歲了`); }}Person.x = '靜態屬性x';
class Chinese extends Person { static bar() {  console.log(`類 ${this.name} 的父類是 ${super.name}`);  super.foo(); } constructor(name, age, gender, kungfu) {  super(name, age, gender);  this.kungfu = kungfu; } martial() {  console.log(`${this.name} 正在修煉 ${this.kungfu} `); }}
class American extends Person { // static y = '靜態屬性y'; static bar() {  console.log(`類 ${this.name} 有自己的 ${this.y} ,還繼承了父類 ${super.name} 的 ${super.x}`); } constructor(name, age, gender, twitter) {  super(name, age, gender);  this.twitter = twitter; } sendTwitter(msg) {  console.log(`${this.name} : `);  console.log(` ${msg}`); }}
American.y = '靜態屬性y';Person.x;  // 靜態屬性xPerson.foo(); // 類 Person 有一個 靜態屬性xChinese.x;  // 靜態屬性xChinese.foo(); // 類 Chinese 有一個 靜態屬性xChinese.bar(); // 類 Chinese 的父類是 PersonAmerican.x;  // 靜態屬性xAmerican.y;  // '靜態屬性yAmerican.foo(); // 類 American 有一個 靜態屬性xAmerican.bar(); // 類 American 有自己的 靜態屬性y ,還繼承了父類 Person 的 靜態屬性xconst p = new Person('Lucy', 20, '女');const c = new Chinese('韓梅梅', 18, '女', '詠春拳');const a = new American('特朗普', 72, '男', 'Donald J. Trump');c.sayHello(); // 你好我是 韓梅梅女士 ,我 18 歲了c.martial(); // 韓梅梅 正在修煉 詠春拳 a.sayHello(); // 你好我是 特朗普先生 ,我 72 歲了a.sendTwitter('推特治國'); // 特朗普 : 推特治國

ES6 之前的 class

ES5 的繼承,實質是先創造子類的實例對象 this,

然后再將父類的方法添加到 this 上面 Parent.apply(this) 。

ES6 的繼承機制完全不同,實質是先創造父類的實例對象 this,所以必須先調用 super 方法,

然后再用子類的構造函數修改this。

為了實現繼承,我們需要先實現一個 extendsClass 函數,它的作用是讓子類繼承父類的靜態成員和實例成員。

function extendsClass(parent, child) { // 防止子類和父類相同名稱的成員被父類覆蓋 var flag = false; // 繼承靜態成員 for (var k in parent) {  flag = k in child;  if (!flag) {   child[k] = parent[k];  } } // 繼承父類prototype上的成員 // 用一個新的構造函數切斷父類和子類之間的數據共享 var F = function () { } F.prototype = parent.prototype; var o = new F(); for (var k in o) {  flag = k in child.prototype;  if (!flag) {   child.prototype[k] = o[k];  } }}
function Person(name, age, gender) { this.name = name; this.age = age; this.gender = this.gender; // 如果將 getter/setter 寫在 prototype 會獲取不到 Object.defineProperty(this, 'fullName', {  get: function () {   var suffix = this.gender === '男' ? '先生' : '女士';   return this.name + suffix;  },  set: function () {   console.log('你已改名為 ' + value + ' ');  }, });}Person.x = '靜態屬性x';Person.foo = function () { console.log('類 ' + this.name + ' 有一個 ' + this.x);}Person.prototype = { constructor: Person, // get fullName() { }, // set fullName(value) { }, sayHello: function () {  console.log('你好我是 ' + this.fullName + ' ,我 ' + this.age + ' 了'); },};
function Chinese(name, age, gender, kungfu) { // 用call改變this指向,實現繼承父類的實例屬性 Person.call(this, name, age, gender); this.kungfu = kungfu;}Chinese.bar = function () { console.log('類 ' + this.name + ' 的父類是 ' + Person.name); Person.foo();}Chinese.prototype = { constructor: Chinese, martial: function () {  console.log(this.name + ' 正在修煉 ' + this.kungfu + ' '); }};extendsClass(Person, Chinese);
function American(name, age, gender, twitter) { Person.call(this, name, age, gender); this.twitter = twitter;}American.y = '靜態屬性y';American.bar = function () { console.log('類 ' + this.name + ' 有自己的 ' + this.y + ' ,還繼承了父類 ' + Person.name + ' 的 ' + Person.x);}American.prototype = { constructor: American, sendTwitter: function (msg) {  console.log(this.name + ' : ');  console.log(' ' + msg); }};extendsClass(Person, American);

TypeScript 中的 class

講完了 JavaScript 中的類,還是沒有用到 抽象類,抽象方法,私有方法這三個概念,由于 JavaScript 語言的局限性,想要實現這三種概念是很困難的,但是在 TypeScript 可以輕松的實現這一特性。

首先我們稍微修改一下例子中的描述,Person 是抽象類,因為一個正常的人肯定是有國籍的,Person 的 sayHello 方法是抽象方法,因為每個國家打招呼的方式不一樣。另外一個人的性別是只能讀取,不能修改的,且是確定的是,不是男生就是女生,所以還要借助一下枚舉。

enum Gender { female = 0, male = 1};
abstract class Person { private x: string = '私有屬性x,子類和實例都無法訪問'; protected y: string = '私有屬性y,子類可以訪問,實例無法訪問'; name: string; public age: number; public readonly gender: Gender; // 用關鍵字 readonly 表明這是一個只讀屬性 public static x: string = '靜態屬性x'; public static foo() {  console.log(`類 ${this.name} 有一個 ${this.x}`); } constructor(name: string, age: number, gender: Gender) {  this.name = name;  this.age = age;  this.gender = gender; } get fullName(): string {  const suffix = this.gender === 1 ? '先生' : '女士';  return this.name + suffix; } set FullName(value: string) {  console.log(`你已改名為 ${value} `); } // 抽象方法,具體實現交由子類完成 abstract sayHello(): void;}
class Chinese extends Person { public kungfu: string; public static bar() {  console.log(`類 ${this.name} 的父類是 ${super.name}`);  super.foo(); } public constructor(name: string, age: number, gender: Gender, kungfu: string) {  super(name, age, gender);  this.kungfu = kungfu; } public sayHello(): void {  console.log(`你好我是 ${this.fullName} ,我 ${this.age} 歲了`); } public martial() {  console.log(`${this.name} 正在修煉 ${this.kungfu} `); }}
class American extends Person { static y = '靜態屬性y'; public static bar() {  console.log(`類 ${this.name} 有自己的 ${this.y} ,還繼承了父類 ${super.name} 的 ${super.x}`); } public twitter: string; public constructor(name: string, age: number, gender: Gender, twitter: string) {  super(name, age, gender);  this.twitter = twitter; } public sayHello(): void {  console.log(`Hello, I am ${this.fullName} , I'm ${this.age} years old`); } public sendTwitter(msg: string): void {  console.log(`${this.name} : `);  console.log(` ${msg}`); }}
Person.x;  // 靜態屬性xPerson.foo(); // 類 Person 有一個 靜態屬性xChinese.x;  // 靜態屬性xChinese.foo(); // 類 Chinese 有一個 靜態屬性xChinese.bar(); // 類 Chinese 的父類是 PersonAmerican.x;  // 靜態屬性xAmerican.y;  // '靜態屬性yAmerican.foo(); // 類 American 有一個 靜態屬性xAmerican.bar(); // 類 American 有自己的 靜態屬性y ,還繼承了父類 Person 的 靜態屬性xconst c: Chinese = new Chinese('韓梅梅', 18, Gender.female, '詠春拳');const a: American = new American('特朗普', 72, Gender.male, 'Donald J. Trump');c.sayHello(); // 你好我是 韓梅梅女士 ,我 18 歲了c.martial(); // 韓梅梅 正在修煉 詠春拳 a.sayHello(); // Hello, I am 特朗普先生 , I'm 72 years olda.sendTwitter('推特治國'); // 特朗普 : 推特治國

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲无限av看| 亚洲成人黄色在线| 欧美大秀在线观看| 亚洲二区中文字幕| 97免费视频在线播放| 国产成人精品视频在线观看| 91热精品视频| 日韩中文字幕在线免费观看| 欧美日韩国产中文字幕| 国内精品中文字幕| 国产主播欧美精品| 久久久噜噜噜久久中文字免| 这里只有精品视频| 欧美日韩国产一区在线| 日韩av日韩在线观看| 久久人人爽国产| 亚洲影影院av| 黄色一区二区在线| 在线观看亚洲视频| 亚洲国产天堂久久综合| 日韩欧美国产高清91| 日韩电影中文字幕在线| 国产精品18久久久久久首页狼| 久久久久久久久久久91| 国产美女久久久| 国产精品免费在线免费| 国产精品久久久久久婷婷天堂| 亚洲成年网站在线观看| 国产91色在线|免| 午夜精品久久久99热福利| 欧美成人精品在线| 欧美黑人性视频| 精品国产乱码久久久久酒店| 日韩av一区在线| 国产精品久久久久久av福利| 亚洲国产精久久久久久| www.久久撸.com| 国产成人鲁鲁免费视频a| 国内精品久久久久久| 欧美性猛xxx| 国产经典一区二区| 国产精品旅馆在线| 日韩欧美999| 久久久噜久噜久久综合| 粉嫩老牛aⅴ一区二区三区| 久久精品欧美视频| 欧美日韩精品在线播放| 高清欧美性猛交xxxx黑人猛交| 免费av一区二区| 色偷偷91综合久久噜噜| 国产精品爽爽ⅴa在线观看| 91色琪琪电影亚洲精品久久| 91在线视频免费| 成人欧美一区二区三区黑人| 亚洲欧美国产日韩天堂区| 日韩精品在线免费播放| 日韩精品免费在线播放| 久久免费视频在线观看| 欧美激情2020午夜免费观看| 国产精品扒开腿做爽爽爽男男| 91丨九色丨国产在线| 精品久久久久久亚洲精品| 国产精品18久久久久久首页狼| 亚洲成人中文字幕| 黑人巨大精品欧美一区免费视频| 国产精品91免费在线| 91黑丝高跟在线| 日本道色综合久久影院| 日韩精品在线免费播放| 国产精品久久久久久影视| 久久精品国产2020观看福利| 亚洲国产欧美久久| 91国产精品电影| 欧美精品性视频| 久久精品91久久久久久再现| 国产成人精品久久二区二区| 亚洲美女激情视频| 正在播放亚洲1区| 亚洲成人免费在线视频| 成人午夜黄色影院| 亚洲精品久久久久久久久| 国产精品久久久久免费a∨| 亚洲成人网在线| 欧美一级片在线播放| 日本午夜精品理论片a级appf发布| 色悠悠久久88| 亚洲资源在线看| 国产精品91在线观看| 久久国产精品久久久久久久久久| 日韩精品视频免费专区在线播放| 91高清视频在线免费观看| 一本色道久久综合狠狠躁篇的优点| 92版电视剧仙鹤神针在线观看| 日韩极品精品视频免费观看| 在线成人中文字幕| 久久久免费av| 日本成熟性欧美| 97在线免费视频| 亚洲毛片一区二区| 亚洲视频电影图片偷拍一区| 中文字幕日韩欧美精品在线观看| 精品久久久久久国产91| 日韩免费在线免费观看| 91免费人成网站在线观看18| 国语对白做受69| 久久久电影免费观看完整版| 国产极品精品在线观看| 亚洲第一av网| 亚洲国产另类 国产精品国产免费| 一区国产精品视频| 欧美在线一级视频| 日韩第一页在线| 91成人精品网站| 国产精品1234| 午夜欧美大片免费观看| 美女av一区二区| 1769国内精品视频在线播放| 日韩精品日韩在线观看| 国产一区二区美女视频| 国产三级精品网站| 亚洲欧美第一页| 91久久久亚洲精品| 26uuu亚洲国产精品| 97国产精品人人爽人人做| 久久久亚洲影院你懂的| 久久久久久久久久国产精品| 日韩精品视频在线观看免费| 中文字幕亚洲字幕| 欧美激情手机在线视频| 日韩小视频在线观看| 精品久久久免费| 综合av色偷偷网| 自拍偷拍免费精品| 日韩免费中文字幕| 日韩69视频在线观看| 欧美性猛交99久久久久99按摩| 国产精品成人国产乱一区| 国产日韩精品在线观看| 亚洲韩国欧洲国产日产av| 另类图片亚洲另类| xvideos亚洲人网站| 成人免费高清完整版在线观看| 国产精品男女猛烈高潮激情| 98视频在线噜噜噜国产| 91精品在线播放| 午夜精品一区二区三区视频免费看| 欧美激情二区三区| 精品久久久久久久久国产字幕| 日韩精品一二三四区| 久久亚洲欧美日韩精品专区| 97在线视频一区| 亚洲一区精品电影| 日韩中文字幕国产| 欧美精品在线看| 欧美日韩成人黄色| 亚洲成年人在线| 国产精品男女猛烈高潮激情| 国产美女直播视频一区| 亚洲国产精品推荐| 亚洲国产成人精品久久久国产成人一区| 亚洲精品女av网站| 国产欧美一区二区三区久久人妖| 一本色道久久88综合亚洲精品ⅰ| 91精品国产91久久久久久不卡|