JS--ES5和ES6继承的区别

1,532 阅读1分钟

ES5 和 ES6 中继承的主要区别是: ES5 的子类通过 proto 查找到的是 Function.prototype, 而 ES6 的子类通过 proto 查找到的是父类。原因是 ES5 和 ES6 子类 this 生成顺序不同。ES5 的继承先生成了子类实例,再调用父类的构造函数修饰子类实例,ES6 的继承先生成父类实例,再调用子类的构造函数修饰父类实例(在 constructor 中,需要使用 super())。

  1. ES5 使用原型形式实现继承, 原型继承的基本结构如下:
function Person(name) {
  this.name = name
}
Person.prototype.sayName = function () {
  console.log(this.name)
}

function Hero() {}
Hero.prototype = new Person('Iron Man')

let p1 = new Hero()
p1.sayName()    // Iron Man

console.log(Hero.__proto__ === Function.prototype)    // true
  1. ES6 使用类实现继承(本质是原型形式的语法糖), 基本的类结构如下:
class Person {
  constructor(name) {
    this.name = name
  }
  sayName() {
    console.log(this.name)
  }
}
class Hero extends Person {
  constructor(name) {
    super(name)
  }
}
let p1 = new Hero('Iron Man')
p1.sayName()    // Iron Man

console.log(Hero.__proto__ === Person)    // true
  1. ES6 中的类有如下特点:
  • class 声明会提升变量并被设为暂时性死区,但不会初始化赋值.下例中如果没有 class 声明就不会报错,有 class 声明则 const foo = new Foo() 会报错。
var Foo = function() {}

{
  const foo = new Foo();    // Uncaught ReferenceError: Cannot access 'Foo' before initialization
  class Foo {
    constructor() {
      this.foo = 37;
    }
  }
}
  • class 声明内部会自动使用严格模式。

  • class 内的所有方法都不可枚举。

  • class 内的所有方法都没有 [[Constructor]]。

  • class 的构造器调用必须使用 new。

  • class 内部不能重写类名。