es6 class创建类

传统创建类方法

Js语言的传统方法是通过构造函数,定义并生成新对象,prototype 属性使您有能力向对象添加属性和方法,是一种基于原型的面向对象系统。

//Person.js
function Person(x,y){
    this.x = x;
    this.y = y;
    this.say=function(){return y}
}

Person.prototype.toString = function (){
    return (this.x + "的年龄是" +this.y+"岁");
}

let person = new Person('张三',12);
console.log(person.toString());//张三的年龄是12岁

class创建类

ES6引入了Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

//Person.js
class Person{
    // 构造
    constructor(x,y){
        this.x = x;
        this.y = y;
        this.z=1;
    }
    p(){
       return 2;
    }
    toString(){
        return (this.x + "的年龄是" +this.y+"岁");
    }
}
export {Person};
//index.js
import {Person} from './Person';
let person = new Person('张三',12);
console.log(person.toString());//张三的年龄是12岁

// 类上面的方法等同于

Person.prototype = {
toString(){ return (this.x + “的年龄是” +this.y+“岁”);},
};

constructor方法,这就是构造方法,this关键字则代表实例对象。
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

定义“类”的方法的时候,前面不需要加上function这个关键字,方法之间不需要逗号分隔
类的所有方法都定义在类的prototype属性上面。
类的构造方法必须使用new关键字

Object.assign方法可以给对象Person动态的增加方法,

Object.assign(Person.prototype, {
  getage(){},
  toValue(){}
});

Class的继承

extends
Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。

//student类通过extends关键字,继承了Person类的所有属性和方法。
class Student extends Person {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.z=3;
    console.log(super.p());//2将super当作一个对象使用
    this.age = 10;
  }
}

super
super表示父类构造函数,用来新建父类的this对象。

子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
super作为对象时,指向父类的原型对象。super指向父类Person.prototype,所以super.p()就相当于Person.prototype.p()

ES5与ES6构造函数的区别
  • ES5原型定义的方法是可枚举的,ES6 类的内部定义的所有方法,都是不可枚举的。
  • ES6的class类必须用new命令操作,而ES5的构造函数不用new也可以执行
  • ES6的class类不存在变量提升,必须先定义class之后才能实例化,不像ES5中可以将构造函数写在实例化之后。
  • ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面。ES6 的继承机制完全不同,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。
由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的。
class A {
  constructor() {
    this.p = 2;
  }
}

class B extends A {
  get m() {
    return super.p;
  }
}

let b = new B();
b.m // undefined
ES6 规定,通过super调用父类的方法时,super会绑定子类的this。
class A {
  constructor() {
    this.x = 1;
  }
  print() {
    console.log(this.x);
  }
}

class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  m() {
    super.print();
  }
}

let b = new B();
b.m() // 2

你可能感兴趣的:(ES6,ES6,javascript)