重学ES6:ES5和ES6中Class类的相同与不同

Posted xzweb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重学ES6:ES5和ES6中Class类的相同与不同相关的知识,希望对你有一定的参考价值。

ES5和ES6中Class类的相同与不同  

先说结论,简而言之ES5用function定义类,ES6用class定义类,class的本质是function,ES6中的类只是语法糖,它并没有改变ES5下类实现的本质。

类的定义

ES5

// ES5函数来描写类
// 声明类
let Animal = function (type) {
  this.type = type
  // 定义实例方法
  this.drink = function () {
    console.log(‘drink‘)
  }
}

// 定义原型方法
Animal.prototype.eat = function () {
  console.log(‘eat food‘)
}

// 实例化
let dog = new Animal(‘dog‘)
let monkey = new Animal(‘monkey‘)

ES6

// ES6 class
// class的本质是ES5用原型链声明类的语法糖
class Animal {
  constructor (type) {
    this.type = type
  }
  eat () {
    console.log(‘eat food‘)
  }
}

let dog = new Animal(‘dog‘)
let monkey = new Animal(‘monkey‘)

ES6类中的set和get方法

  • set用于设置属性(无返回值)
  • get用于读取属性(有返回值)
let _age = 4
class Animal {
  constructor (type) {
    this.type = type
  }
  get age () {
    return _age
  }
  set age (val) {
    this.realage = val
  }
  eat () {
    console.log(‘eat food‘)
  }
}

let dog = new Animal(‘dog‘)
console.log(dog.age) // 4
dog.age = 5 // 未生效 get定义的为只读属性
console.log(dog.age) // 4
console.log(dog.realage) // 5

ES5类中的 实例方法&原型方法&静态方法

  • 实例方法只有实例可以调用

  • 实例方法可以调用静态方法,不能调用原型方法

  • 原型方法可以被实例和构造函数访问到

  • 原型方法只可以调用静态方法

  • 静态方法只有构造函数可以调用

 

ES5中定义三种方法及调用关系

let Animal = function (type) {
  this.type = type
  // 实例方法
  this.drink = function () {
    // 实例方法可调用类的静态方法
    Animal.walk()
    console.log(‘drink‘)
  }
}

// 原型方法
Animal.prototype.eat = function () {
  // 原型方法可调用类的静态方法
  Animal.walk()
  console.log(‘eat food‘)
}

// 静态方法
Animal.walk = function () {
  console.log(‘walking‘)
}

let dog = new Animal(‘dog‘)
dog.drink() // walking drink
dog.eat() // walking eat food
Animal.walk() // walking静态方法只能由<类自身&实例方法&原型方法>调用,实例对象无法调用
// dog.walk() // dog.walk is not a function  实例对象无法调用静态方法

 

ES6类中的 实例方法&原型方法&静态方法

  • 实例方法=原型方法 类中直接定义的实例方法默认就是ES5中的原型方法(语法糖)

  • 静态方法用static前缀定义

  • 静态方法只有构造函数可以调用,原型方法是实例和构造函数都可以调用,是共享的方法。

class Animal {
  constructor (type) {
    this.type = type
  }
  // 定义实例对象的方法
  eat () {
    // 使用静态方法,以类形式访问,而非this访问
    Animal.walk()
    console.log(‘eat food‘)
    console.log(this.type) // 类的例实例对象的方法可以获取到实例对象的信息,输出dog
  }
  // static 定义类的静态方法
  static walk () {
    console.log(‘walking‘)
    console.log(this.type) // 类的静态方法无法获取到实例对象的信息,输出undefined
  }
}
let dog = new Animal(‘dog‘)
dog.eat() // walking ; undefined ; eat food ; dog
Animal.walk() // walking ; undefined ;
dog.walk() // dog.walk is not a function
// 得出结论:需要访问实例对象的信息时用实例对象的方法,否则使用static静态方法
// 实例方法就是只有实例可以调用,静态方法只有构造函数可以调用,原型方法是实例和构造函数都可以调用,是共享的方法。

 

ES5 子类

  • .call方法指向父类

  • 设置原型链指向相同

let Animal = function (type) {
  this.type = type
  // 实例方法
  this.drink = function () {
    // 实例方法可调用类的静态方法
    Animal.walk()
    console.log(‘drink‘)
  }
}

// 原型方法
Animal.prototype.eat = function () {
  // 原型方法可调用类的静态方法
  Animal.walk()
  console.log(‘eat food‘)
}

// 静态方法
Animal.walk = function () {
  console.log(‘walking‘)
}

let Dog = function () {
  // 初始化父类的构造函数,call的作用是改变this指向dog的实例
  Animal.call(this, ‘dog‘)
  this.run = function () {
    console.log(‘run‘)
  }
}

// 两个原型链指向相同,子类才可以用父类的方法
Dog.prototype = Animal.prototype

let dog = new Animal(‘dog‘)
dog.eat()  // 实例对象能调用类定义在原型上的实例对象的方法
// dog.walk() // 实例对象不能调用类的静态方法

let realdog = new Dog(‘realdog‘)
realdog.eat()
realdog.run()

 

ES6 子类

  • extends定义子类,super指向父类的原型对象,可以调用父类的属性和方法。

class Animal {
  constructor (type, age) {
    this.type = type
    this.age = age
  }
  detail () {
    console.log(this.type + ‘ ‘ + this.age)
  }
}

class Dog extends Animal {
  // 定义子类的构造函数
  constructor (type, age, sex) {
    // super()要和父类的constructor一致
    // super关键字表示调用父类的构造方法,也就是父类constructor中的内容
    super(type, age)
    this.sex = sex
  }
  ndetail () {
    console.log(this.type + ‘ ‘ + this.age + ‘ ‘ + this.sex)
  }
}

// let cat = new Animal(‘cat‘, 20)
// cat.detail()
let dog = new Dog(‘dog‘, 5, ‘gong‘)
dog.ndetail()

 

以上是关于重学ES6:ES5和ES6中Class类的相同与不同的主要内容,如果未能解决你的问题,请参考以下文章

ES6 Class

重学ES6:函数和箭头函数

ES6 - 基础学习: Class 类

ES6新特性:使用新方法定义javascript的Class

ES6构造函数class 和 ES5构造函数语法

ES6-18:class类及其继承