最近心血來潮倒騰了下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博客鏈接方便接下來進一步學習