ES6中Class的一些基本用法

最近心血來潮倒騰了下ES6的Class,記錄下它的一些簡單用法備忘(所有代碼均運行在vue 環境)

class類的構建 

構建

 新建一個people.js文件,在people.js中寫入代碼如下

export default class People{
    constructor(name,age){//new People時候會調用
        this.name = name;
        this.age = age;
    }
    peopleRun(){
        console.log('peopleRun')
    }
    static sayEnglish(){//靜態方法
        console.log('sayEnglish')
    }
}

創建了一個People類,並對外暴露 

簡單的介紹下constructor

constructor方法是類的默認方法,通過new命令生成對象實例時,自動調用該方法。一個類必須有constructor方法,如果沒有顯式定義,一個空的constructor方法會被默認添加一個空函數。constructor方法默認返回實例對象(即this),完全可以指定返回另外一個對象。例如如下代碼

class foo{
  constructor() {
    return Object.create(null);
  }
}
new Foo() instanceof Foo // false

上面代碼中,constructor函數返回了一個全新的對象,結果導致實例對象不是Foo類的實例。 

簡單的介紹下靜態方法

類相當於實例的原型,所有在類中定義的方法,都會被實例繼承。如果在一個方法前,加上static關鍵字,就表示該方法不會被實例繼承,而是直接通過類來調用,這就稱爲“靜態方法”。在people中sayEnglish就是個靜態方法,該方法不會被實例繼承,實例中無法調用

類的實例化  

實例化 

類的實例化很簡單,直接在需要用到的地方引入並且new出一個實例對象即可

import People from './util/people'
let people  = new People('張三',19);
people.peopleRun(); //控制檯打印peopleRun

與 ES5 一樣,類的所有實例共享一個原型對象。如下代碼將輸出true

var People1= new People('張三',3);
var People2= new People('李四',2);

People1.__proto__ === People2.__proto__  //true

 

類的extends繼承

基本用法

Class 可以通過extends關鍵字實現繼承,這比 ES5 的通過修改原型鏈實現繼承,要清晰和方便很多。

新建一個boy.js文件,代碼如下

import People from "./people";

export default class Boy extends People{
    constructor(){
        super('張三',10);// 調用父類的constructor(x, y)
    }
    boySay(){
        console.log('boySay')
    }
}

以上代碼創建了一個Boy類並且繼承了People類 

需要注意的地方是,在子類的構造函數中,只有調用super之後,纔可以使用this關鍵字,否則會報錯。這是因爲子類實例的構建,基於父類實例,只有super方法才能調用父類實例。

實例化

import Boy from './util/boy'
let boy  = new Boy();
boy.peopleRun();//控制檯打印peopleRun
boy.boySay();//控制檯打印boySay

以上代碼實例化了一個boy並且調用了自身的boySay方法和繼承來的peopleRun方法

Mixin 模式多繼承 

Mixin 指的是多個對象合成一個新的對象,新對象具有各個組成成員的接口。它的最簡單實現如下。

const a = {
  a: 'a'
};
const b = {
  b: 'b'
};
const c = {...a, ...b}; // {a: 'a', b: 'b'}

上面代碼中,c對象是a對象和b對象的合成,具有兩者的接口。

下面我們來實現一個更完備的實現,將多個類的接口“混入”(mix in)另一個類:

我們在新建一個dog類,新建文件dog.js代碼如下


export default class Dog extends null{
    constructor(name,age){
        this.name = name;
        this.age = age
    }
    dogSay(){
        console.log('汪汪汪')
    }
}

接下來我們在新建一個mix類,用來繼承dog和boy類

新建文件mix.js代碼如下

function mix(...mixins) {
    class Mix {
      constructor() {
        for (let mixin of mixins) {
          copyProperties(this, new mixin()); // 拷貝實例屬性
        }
      }
    }
  
    for (let mixin of mixins) {
      copyProperties(Mix, mixin); // 拷貝靜態屬性
      copyProperties(Mix.prototype, mixin.prototype); // 拷貝原型屬性
    }
  
    return Mix;
  }
  
function copyProperties(target, source) {
    for (let key of Reflect.ownKeys(source)) {
      if ( key !== 'constructor'
        && key !== 'prototype'
        && key !== 'name'
      ) {
        let desc = Object.getOwnPropertyDescriptor(source, key);
        Object.defineProperty(target, key, desc);
      }
    }
}

//類的構建
import Boy from './boy'//引入boy類
import Dog from './dog'//dog類
export default class Mixtest extends mix(Boy, Dog) {
    constructor(){
        super();
    }
    minSay(){
        console.log('minSay')
    }

}

實例化如下

import Mixtest from './util/mix'
let mixtest  = new Mixtest('小李',10);
mixtest.peopleRun();//報錯,無法調用
mixtest.boySay();//控制檯打印boySay
mixtest.dogSay();//控制檯打印汪汪汪

下面我們來吧實現多繼承的兩個函數封裝到我們的extend類裏面,方便複用,新建extend.js文件,代碼如下

let copyProperties = (target, source)=> {
    for (let key of Reflect.ownKeys(source)) {
        if ( key !== 'constructor'
        && key !== 'prototype'
        && key !== 'name'
        ) {
        let desc = Object.getOwnPropertyDescriptor(source, key);
        Object.defineProperty(target, key, desc);
        }
    }
}


export default class Extend{
    mixExtend(...mixins){
        class Mix {
            constructor() {
            for (let mixin of mixins) {
                copyProperties(this, new mixin()); // 拷貝實例屬性
            }
            }
        }
        
        for (let mixin of mixins) {
            copyProperties(Mix, mixin); // 拷貝靜態屬性
            copyProperties(Mix.prototype, mixin.prototype); // 拷貝原型屬性
        }
        
        return Mix;
    }
}

接着吧mix.js代碼改爲如下:


import Extend from './extend.js'//引入繼承類
let extend = new Extend()//實例化一個繼承類

//類的構建
import Boy from './boy'//引入boy類
import Dog from './dog'//dog類
export default class Mixtest extends extend.mixExtend(Boy, Dog) {// extend.mixExtend(Boy, Dog)  調用extend實例裏面的mixExtend方法返回對用的類給Mixtest繼承
    constructor(){
        super();
    }
    minSay(){
        console.log('minSay')
    }

}

實例化Mixtest類是一樣的操作,得到的效果也一樣

最後在貼上大神  阮一峯大神ES6博客鏈接方便接下來進一步學習 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章