ES6 Class类、与ES5继承的区别

417 阅读2分钟

ES5中实现类

  • 构造函数法
function Person(name,age){
   this.name = name;
   this.age = age;
   this.say = function (){
      console.log(`${this.name} + ${this.age}`)
   }
}
zs = new Person('张三'12);
zs.say();// 张三12
console.log(zs.name); // 张三

优点:遇到new出来的每个实例都有一份属于自身的数据

缺点:在定义函数时,内存造成很大浪费

  • 原型对象法
function Person (){}
Person.prototype.name = '张三';
Person.prototype.age = '张三';
Person.prototype.say = function (){
  console.log(`${this.name}+ ${this.age}`)
}
let zs = new Person('张三'12);
zs.say();
console.log(zs.name);//张三

优点:共用一个类的方法,节省大量的存储空间 缺点:所有实例公用一份数据,数据赋值和使用比较麻烦

  • 构造函数 + 原型对象法
function Person(name,age){
  this.name = name;
  this.age = age;
}
Person.prototype.say = function(){
   console.log(`${this.name}`)
}

优点:结合上两种方法

ES6 Class实现类

基本语法
// 类声明
class Person {}
// 类表达式
var Student = class{}
类的构造函数

通过类的构造方法constructor创建实例时向类传递参数,一个类只有一个构造函数

class Person {
   constructor(name,age) {
      this.name = name;
      this.age = age;
   }
}
var p = new Person('张三',12)
console.log(p) ;// Person{name:'张三',age:12}
类的实例方法
class Person {
   constructor(name,age){
      this.name = name;
      this.age = age;
   }
   running(){
      console.log(`${this.name} is running`)
   }
}
var p = new Person('张三'12)
p.running()
类的访问器方法
class Person {
   constructor(name){
      this.name = name;
   }
   // 类的访问器方法
   get name(){
     return this._name
   }
   set name(val){
      this._name = val
   }
}
const p = new Person('张三')

通过getter、setter访问器函数,可以对读写进行拦截操作。

类的静态方法

静态方法:类独有,实例没有,通过static关键字来描述一个类中的一个方法为静态方法。

class Person {
  constructor(name){
    this._name = name;
  }
  static greeting(){
    console.log(`nihao`)
  }
}
const p = new Person('张三')
Person.greeting() // 成功
p.greeting()  // 报错,没有此方法

类的静态属性

静态属性指的是Class本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。

// 旧写法
class Foo {}
Foo.prop = 1;
Foo.prop // 1

// 新写法
class Foo{
   static prop = 1
   constructor(){
      console.log(Foo.prop)  // 1
   }
}
// 类的静态属性只要在上面的实例属性写法前面,加上static关键字就可以了。
实现继承
class Person {
  constructor(name) {
     this.name = name
  }
  running(){
     console.log(`${this.name} is running`)
  }
}
// extends 关键字继承父类
class Student extends Person {
  constructor(name,sno){
    // super 调用父类的构造函数
    // 传入自定义参数
    super(name)
    this.sno = sno
  }
  studying(){
    console.log(`${this.name} is studying`)
  }
}
const s1 = new Student('张三',1212);
s1.running() // 张三 is running
s1.studying()  张三 is studying

类的实例属性

类的实例属性可以用等式,写入类的定义之中。

Class Foo(){
   prop = 1
   constructor(){
      console.log(this.prop) // 1 
   }
}

Class静态方法

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。

class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod()   // TypeError: foo.classMethod is not a function

如果静态方法包含this关键字,这个this指的是类,而不是实例。

class Foo {
  static bar () {
    this.baz();
  }
  static baz () {
    console.log('hello');
  }
  baz () {
    console.log('world');
  }
}
Foo.bar() // hello

父类的静态方法,可以被子类继承

class Foo {
  static classMethod() {
    return 'hello';
  }
}
class Bar extends Foo {
}
Bar.classMethod() // 'hello'

静态方法也是可以从super对象上调用的

class Foo {
  static classMethod() {
    return 'hello';
  }
}
class Bar extends Foo {
  static classMethod() {
    return super.classMethod() + ', too';
  }
}
Bar.classMethod() // "hello, too"

ES6中class类继承与ES5继承的区别

  • ES5的继承实质是先创建子类的实例对象,然后再将父类的方法添加到this上
  • ES6的继承,实质是先创建父类的实例对象this(先调用父类的super()方法),再用子类的构造函数修改this。

具体的:ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。子类必须再constructor方法中调用super方法。