類的概念

雖然 JavaScript 中有類的概念励七,但是可能大多數(shù) JavaScript 程序員并不是非常熟悉類妈倔,這里對類相關(guān)的概念做一個簡單的介紹楼熄。

  • 類(Class):定義了一件事物的抽象特點(diǎn)疚察,包含它的屬性和方法
  • 對象(Object):類的實(shí)例运褪,通過 new 生成
  • 面向?qū)ο螅∣OP)的三大特性:封裝、繼承狰右、多態(tài)
  • 封裝(Encapsulation):將對數(shù)據(jù)的操作細(xì)節(jié)隱藏起來杰捂,只暴露對外的接口。外界調(diào)用端不需要(也不可能)知道細(xì)節(jié)棋蚌,就能通過對外提供的接口來訪問該對象嫁佳,同時也保證了外界無法任意更改對象內(nèi)部的數(shù)據(jù)
  • 繼承(Inheritance):子類繼承父類,子類除了擁有父類的所有特性外谷暮,還有一些更具體的特性
  • 多態(tài)(Polymorphism):由繼承而產(chǎn)生了相關(guān)的不同的類蒿往,對同一個方法可以有不同的響應(yīng)。比如 Cat 和 Dog 都繼承自 Animal湿弦,但是分別實(shí)現(xiàn)了自己的 eat 方法瓤漏。此時針對某一個實(shí)例,我們無需了解它是 Cat 還是 Dog,就可以直接調(diào)用 eat 方法蔬充,程序會自動判斷出來應(yīng)該如何執(zhí)行 eat
  • 存取器(getter & setter):用以改變屬性的讀取和賦值行為
  • 修飾符(Modifiers):修飾符是一些關(guān)鍵字俯在,用于限定成員或類型的性質(zhì)。比如 public 表示公有屬性或方法
  • 抽象類(Abstract Class):抽象類是供其他類繼承的基類娃惯,抽象類不允許被實(shí)例化。抽象類中的抽象方法必須在子類中被實(shí)現(xiàn)
  • 接口(Interfaces):不同類之間公有的屬性或方法肥败,可以抽象成一個接口趾浅。接口可以被類實(shí)現(xiàn)(implements)。一個類只能繼承自另一個類馒稍,但是可以實(shí)現(xiàn)多個接口

ES5 類的寫法

function Person(name) {
    this.name = name;
    this.age = 0;
}

Person.prototype.addAge = function () {
    this.age++;
    console.log(this,this.name, this.age);
};

let person1 = new Person("Nick");
person1.addAge(); // Person { name: 'Nick', age: 1 } 'Nick' 1

let person2 = new Person("Ming");
person2.addAge(); // Person { name: 'Ming', age: 1 } 'Ming' 1

ES6 類的寫法

class Person {
    static single = null;

    constructor(name) {
        this.name = name;
        this.age = 0;
    }

    addAge() {
        this.age++;
        console.log(this, this.name, this.age);
    }

    static getInstance() {
        if (this.single === null) {
            this.single = new Person("Hi");
        }
        return this.single;
    }
}

let person1 = new Person("Nick");
person1.addAge(); // Person { name: 'Nick', age: 1 } 'Nick' 1

let person2 = new Person("Ming");
person2.addAge(); // Person { name: 'Ming', age: 1 } 'Ming' 1

Person.getInstance().addAge(); // Person { name: 'Hi', age: 1 } 'Hi' 1

ES5 類的繼承

/**
 * js 類的實(shí)現(xiàn)
 * @type {Base}
 */
var Base = (function () {
    function Base(name) {
        this.name = name;
    }

    Base.prototype.getName = function () {
        console.log(this.name);
    }
    return Base;
})();

let base = new Base("Nick");
base.getName(); // Nick

var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({__proto__: []} instanceof Array && function (d, b) {
            d.__proto__ = b;
        }) ||
        function (d, b) {
            for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
        };
    return function (d, b) {
        extendStatics(d, b);

        function __() {
            this.constructor = d;
        }

        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();

/**
 * js 繼承
 * @type {function(*=): (*|Device)}
 */
var Device = (function (_super) {
    __extends(Device, _super);

    function Device(name) {
        return _super.call(this, name) || this;
    }

    return Device;
})(Base);

let device = new Device("Jack");
device.getName(); //Jack

ES6 類的繼承

使用 extends 關(guān)鍵字實(shí)現(xiàn)繼承皿哨,子類中使用 super 關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù)和方法。

class Base {
    constructor(name) {
        this.name = name;
    }

    getName() {
        console.log(this.name);
    }
}

let base = new Base('Nick');
base.getName(); // Nick

class Device extends Base {
    constructor(name) {
        super(name);
    }
}
let device = new Device('Jack');
device.getName(); //Jack

ES5 多態(tài)

function study(person) {
    person.study();
};

function Teacher(name) {
    this.name = name
};

Teacher.prototype.study = function () {
    console.log(` Teacher ${this.name} do something!`);
};

function Student(name) {
    this.name = name;
}

Student.prototype.study = function () {
    console.log(` Student ${this.name} do something!`);
};

let teacher = new Teacher("Nick");
study(teacher);
let student = new Student("Jack");
study(student);

ES6 多態(tài)

abstract class PersonDao {
    abstract study(): string;
}

class Student extends PersonDao {
    name: string;

    constructor(name) {
        super();
        this.name = name;
    }

    study(): string {
        return `Student ${this.name} do something!`;
    }
}

class Teacher extends PersonDao {
    name: string;

    constructor(name) {
        super();
        this.name = name;
    }

    study(): string {
        return `Teacher ${this.name} do something!`;
    }

}

let teacher: PersonDao = new Teacher("Nick");

console.log(teacher.study());

let student: PersonDao = new Student("Jack");
console.log(student.study());

存取器

使用 getter 和 setter 可以改變屬性的賦值和讀取行為:

class Animal {
    constructor(name) {
        this.name = name;
    }
    get name() {
        return 'Jack';
    }
    set name(value) {
        console.log('setter: ' + value);
    }
}

let a = new Animal('Kitty'); // setter: Kitty
a.name = 'Tom'; // setter: Tom
console.log(a.name); // Jack

ES7 靜態(tài)屬性和方法

class Animal {
 static name='Hi';
    static isAnimal(a) {
        return a instanceof Animal;
    }
}

let a = new Animal('Jack');
console.log(Animal.name); // Hi
Animal.isAnimal(a); // true
a.isAnimal(a); // TypeError: a.isAnimal is not a function
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末纽谒,一起剝皮案震驚了整個濱河市证膨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鼓黔,老刑警劉巖央勒,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異澳化,居然都是意外死亡崔步,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門缎谷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來井濒,“玉大人,你說我怎么就攤上這事列林∪鹉悖” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵希痴,是天一觀的道長者甲。 經(jīng)常有香客問我,道長润梯,這世上最難降的妖魔是什么过牙? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮纺铭,結(jié)果婚禮上寇钉,老公的妹妹穿的比我還像新娘。我一直安慰自己舶赔,他們只是感情好扫倡,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般撵溃。 火紅的嫁衣襯著肌膚如雪疚鲤。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天缘挑,我揣著相機(jī)與錄音集歇,去河邊找鬼。 笑死语淘,一個胖子當(dāng)著我的面吹牛诲宇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惶翻,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼姑蓝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吕粗?” 一聲冷哼從身側(cè)響起纺荧,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颅筋,沒想到半個月后宙暇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡议泵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年客给,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肢簿。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡靶剑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出池充,到底是詐尸還是另有隱情桩引,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布收夸,位于F島的核電站坑匠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏卧惜。R本人自食惡果不足惜厘灼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咽瓷。 院中可真熱鬧设凹,春花似錦、人聲如沸茅姜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奋姿,卻和暖如春锄开,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背称诗。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工萍悴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人寓免。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓退腥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親再榄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容