最近心血来潮倒腾了下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(param={}) { for (let mixin of mixins) { copyProperties(this, new mixin(param)); // 拷贝实例属性 } } } 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(param={}) { for (let mixin of mixins) { copyProperties(this, new mixin(param)); // 拷贝实例属性 } } } 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博客链接方便接下来进一步学习