ECMAScript6基础学习教程(六)类

2021-01-14 10:39:53 浏览数 (1)

ES6里引入Class概念,非常类似其他面向对象语言(比如Java)。实际上,Class只是简化了对象原型方法的语法,实现原理依旧是ES5构造函数和对象原型。但是,ES6中类的继承,和ES5原型链继承略有不同。

1. Class语法

用ES6的class定义类:

代码语言:javascript复制
class Vehicle {
    // 构造函数
    constructor(name) {
        this.name = name;
    }
    // 实例方法
    ignition() {
        console.log("Start up:"   this.name);
    }
    // 静态方法
    static getType(){
        console.log("Type: Vehicle");
    }
    static getName() {
      console.log("Name: Vehicle");
    }

    // 静态变量(ES7语法)
    static defaultProps = {color: "red"};

    // 存储器属性
    set prop(value){
      console.log("setter:"   value);
      this.value= value;
    }
    
    get prop(){
      return this.value;
    }
}
var vehicle = new Vehicle ('vehicle');
vehicle.prop= 1; // setter:1
console.log(vehicle.prop); // 1
vehicle.ignition(); // "Start up:vehicle"

转为ES5是:

代码语言:javascript复制
function Vehicle (name) {
  this.name = name;
}
// 实例方法
Vehicle.prototype.ignition = function () {
  console.log("Start up:"   this.name);
}
// 静态方法
Vehicle.getType = function (){
  console.log("Type: Vehicle");
}
Vehicle.getName= function (){
  console.log("Name: Vehicle");
}
// 静态变量
Vehicle.defaultProps = {color: "red"};

class声明的类的特点为:

  • 所有方法都定义在原型属性Function.prototype上。
  • 必须有constructor方法,如果没有定义,会默认添加一个空的构造函数。
  • 必须用new创建类的实例,否则会抛错TypeError("Cannot call a class as a function");
  • class不存在变量提升。下面代码会抛错:
代码语言:javascript复制
new Foo(); // TypeError: Foo is not a function
class Foo {};
2. 类的继承:extend

延续上面的例子,创建Vehicle的子类Car

代码语言:javascript复制
class Car extends Vehicle {
    constructor(name){
        super(name);
        this.wheels = 4;
    }
    // 实例方法
    drive(){
        this.ignition();
        console.log("Rolling on all " this.wheels "wheels!")
    }
    // 静态方法
    static getType(){
        console.log("Type: Car");
    }
}

var car = new Car('smart'); 
car.drive(); // Start up:smart
// 类实例无法访问静态方法
console.log(car.getType); //undefined
// 只有类本身可以调用静态方法
Car.getType(); //Type: Car

ES6实现继承的原理与ES5完全不同:

  • ES5的继承:先创建子类实例,然后将父类原型上的方法添加到子类实例上。
  • ES6的继承:先创建父类实例,然后子类实例this指向父类this,并且进行修改。

正因为ES6做继承时,是先创建父类实例,因此,有如下两个特性:

  1. 继承时,子类一旦显性声明了constructor函数,就必须在构造函数里面调用super()方法,从而取得父类this对象(也可以不显性声明constructor函数,ES6会在默认生成的构造方法里面调用super())。
  2. 允许定义继承原生数据结构(Array, String等)的子类,比如:
代码语言:javascript复制
class myArray extends Array{
  constructor(...args) {
    super(...args);
  }
}

var array = new myArray();
array.push(2);
array.length; //1
array[0]; //2
小结

在React中,实现组件用的就是ES6中class语法,例如:

代码语言:javascript复制
import React from 'react';

export default class myTable extends React.Component {
  constructor(props) {
    super(props);
  }
  ...
}

0 人点赞