从ES5 的角度看 ES6中的 class

前言

ES6的 class 是语法糖, 相当好用, 主要介绍几个关键的概念

  1. 仿类结构
  2. 类的声明
  3. 静态成员
  4. 类的继承

1. ES5 中的仿类结构

在ES6之前没有class语法, 我们仿写一个类结构

var Person = function() {
    this.name = name
}

Person.prototype.sayName = function() {
    console.log(this.name)
}

var p = new Person('zmj')
p.sayName()

Person是一个构造函数, sayName()方法被指派到原型上, 因此Person的所有实例都共享了sayName方法

2. ES6 类的声明

将上例改写成类

class Person {
    // 相当于 Person 的构造函数, 私有属性应该写在这里
    constructor(name) {
        this.name = name
    }

    // 相当于Person.prototype.sayName
    sayName() {
        console.log(this.name)
    }
}
var p = new Person('zmj')
p.sayName()

与ES5写法的区别:

  1. 类声明不会被提升, 与 let 相似
  2. 所有代码都处于严格模式
  3. 不可枚举

其实上面的类结构等价于下面的代码

let Person = (function () {
    "use strict"
    const Person = function(name) {
        this.name = name
    }

    Object.defineProperty(Person.prototype, 'sayName', {
        value: function() {
            console.log(this.name)
        },
        enumerable: false,
        writable: true,
        configurable: true
    })

    return Person
})()

var p = new Person('zmj')
p.sayName()

3. 静态成员

首先要理解静态成员的含义.

静态成员是类所有的, 不需要创建实例就可以调用(通过类名直接调用)

在ES5中的例子

var Person = function(name) {
    this.name = name
}

Person.create = function(name) {
    return new Person(name)
}

Person.prototype.sayName = function() {
    console.log(this.name)
}

var p = Person.create('zmj')
p.sayName()

Person.create就是所谓的静态方法. 它的数据不依赖任何类的实例

可以直接通过类名.方法名直接调用, 不需要new一个新的实例

在ES6中简化了该操作, 只要在方法名上加上static即可.

class Person() {
    static create(name) {
        return new Person(name)
    }
}

4. 继承

在ES5中, 实现继承是一个很麻烦的事情.

实现一个继承, 父类是一个矩形类, 子类是正方形类

function Reactangle(length, width) {
    this.length = length
    this.width = width
}

Reactangle.prototype.getArea = function() {
    return this.length * this.width
}

function Square(length) {
    Reactangle.call(this, length, length)
}

Square.prototype = Object.create(Reactangle.prototype, {
    constructor: {
        value: Square,
        enumerable: true,
        writable: true,
        configurable: true
    }
})

var square = new Square(3)
square.getArea()

必须用Object.create 关联子类和父类的原型, 并且在子类的构造方法中还要使用Reactangle.call()方法

用ES6重写

class Rectangle {
    constructor(length, width) {
        this.length = length
        this.width = width
    }

    getArea() {
        return this.length * this.width
    }
}

class Square extends Rectangle {
    constructor(length) {
        // 与 Rectangle.call(this, length, length) 相同
        super(length, length)
    }
}

var square = new Square(3)
上一篇:es5实现批量的并发请求


下一篇:ES6构造函数class 和 ES5构造函数 语法介绍