ES6 類

  • 原型如何實現(xiàn)繼承,Class 如何實現(xiàn)繼承,Class 本質(zhì)是什么?
原型繼承回顧
//創(chuàng)建構(gòu)造函數(shù)User
function User(name, email) {
    this.name = name;
    this.email = email;

    // a --- info 每次實例化都會重新生成一個,消耗內(nèi)存
    this.info = function() {
        console.log(`Hi I am ${this.name}`)
    }
}

// b --- info 定義到原型對象
User.prototype.info = function() {
    console.log(`Hi I am ${this.name}`)
}

//創(chuàng)建 兩個實例對象
const protein = new User('protein', 'i@protein.com')
const tomato = new User('tomato', 'i@tomato.com')

// b --- info 重寫原型對象的方法
User.prototype.info = function() {
    console.log(`Hi I am ${this.name}, my email is ${this.email}`)
}
ES6 類 基本語法
// 聲明類 typeof 是 function 一種特殊的函數(shù) 因為沒有函數(shù)提升 必須在聲明之后才能使用


class User {
    // 定義構(gòu)造函數(shù)
    constructor(name, email) {
        this.name = name;
        this.email = email;
    }

    // 定義 info 方法
    info() {
        console.log(`Hi I am ${this.name}, my email is ${this.email}`);
    }

    // 定義靜態(tài)方法 只能在原型對象上調(diào)用 類似于 Array.from() 區(qū)別于 arr.push()
    description() {
        console.log(`this is a class`);
    }

    // set 關(guān)鍵字定義屬性或者方法
    set github(value) {
        this.githubName = value;
    }
    // get 對應(yīng)set
    get github() {
        return `https://github.com/${this.githubName}`;
    }
}

// 創(chuàng)建 兩個實例對象
const protein = new User('protein', 'i@protein.com')
const tomato = new User('tomato', 'i@tomato.com')

// 使用 set get
protein.github = 'shadow-fiend'; // "shadow-fiend"
protein.github // "https://github.com/shadow-fiend"
  • 首先用 class 定義了一個“類”,可以看到里面有一個 constructor 方法,這就是構(gòu)造方法,而 this 關(guān)鍵字則代表實例對象。簡單地說,constructor 內(nèi)定義的方法和屬性是實例對象自己的,而 constructor 外定義的方法和屬性則是所有實力對象可以共享的。
類的繼承
Class Animal {
    constructor(name) {
        this.name = name;
        this.belly = [];
    }

    eat(food) {
        this.belly.push(food);
    }

    speak() {
        console.log(`Hi I am ${this.name}`);
    }
}

// ES5 實現(xiàn)繼承 ES5 --> 
function Dog() { // ES5 --> 創(chuàng)建 Dog 構(gòu)造函數(shù)
    Animal.call(this, name, age); // ES5 --> 調(diào)用積類構(gòu)造函數(shù)
    this.name = name;
    this.age = age;
}

Dog.prototype = new Animal(); // ES5 --> Dog 原型對象指向 Animal 對象的實例 原型對象的 constructor 會發(fā)生改變
Dog.prototype.constructor = Dog; // ES5 --> 原型對象的 constructor 在給它指回去


// ES6 實現(xiàn)繼承
Class Dog extends Animal {
    constructor(name, age) {
        super(name); // 否則在后面獲取不到 this 值
    }

    bark() {
        console.log(`bark bark!`);
    }

    speak() { // 子類可以重寫父類的方法
        console.log(`bark bark Hi I am ${this.name}`);
    }
}

const Protein = new Dog('protein', 2);
  • Class 之間可以通過 extends 關(guān)鍵字實現(xiàn)繼承,這比 ES5 的通過修改原型鏈實現(xiàn)繼承,要清晰和方便很多。上面定義了一個 Dog 類,該類通過 extends 關(guān)鍵字,繼承了Animal 類的所有屬性和方法。
  • super 關(guān)鍵字,它指代父類的實例 ( 即父類的 this 對象 ) 。子類必須在 constructor方法中調(diào)用 super 方法,否則新建實例時會報錯。這是因為子類沒有自己的 this 對象,而是繼承父類的 this 對象,然后對其進行加工。如果不調(diào)用 super 方法,子類就得不到 this 對象。
  • ES6 的繼承機制,實質(zhì)是先創(chuàng)造父類的實例對象 this ( 所以必須先調(diào)用super方法 ) ,然后再用子類的構(gòu)造函數(shù)修改 this 。
ES6 類 擴展內(nèi)建對象數(shù)組
Class movieCollection extends Array {
    constructor(name, ...items) {
        super(...items);
        this.name = name
    }

    add(movie) {
        this.push(movie);
    }

    topRated(limit = 3) {
        return this.sort((a, b) => (a.scores >= b.scores) ? -1 : 1).slice(0, limit);
    }
}

const movies = new movieCollection('favorite movies',
    { name: 'The Croods', scores: 8.7 },
    { name: 'The ShawThank Redemption', scores: 9.6 },
    { name: 'Leon', scores: 9.4 },
    { name: 'Days of Summer', scores: 8.0 }
)

movies.push({ name: 'Pride & Prejudice', score: 8.4 })
console.table(movies.topRated());
// 可以用 for of 來循環(huán)除 name 之外的數(shù)組的屬性
for(let movie of movies) {console.log(movie)}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容