1.基于原型的继承(ES5)
对象.__proto__===其构造函数.prototype
构造函数继承
function SuperType(){this.color = "red"}function SubType(){SuperType.call(this) // 继承父类的 this}let a = new SubType()console.log(a.color) // red
原型继承-本质就是重写原型对象
组合形式
function Person1(name,age){this.name = name;this.age = age} // 创建构造函数Person1.prototype.sayHi = function(){console.log('你好,我是'+this.name)}function Person2(name,age,sex){Person1.call(this,name,age) // 原型继承,Person1的原型继承给Person2this.sex = sex}let person1 = new Person1('frank', 18)// 构造函数继承;person1 原型上就也有了 sayHi 属性let person2 = new Person2('frank', 18)console.log(person1) // person1没有sex但原型上有sayHi这个函数console.log(person2) // person2有sex,但原型中没有sayHi函数
2.基于 class 的继承(ES6)
constructor方法是一个特殊的方法,这种方法用于创建和初始化一个由class创建的对象。一个类只能拥有一个名为 “constructor”的特殊方法- 一个构造函数可以使用
super关键字来调用一个父类的构造函数 super()之后才能调用thisclass Person1 {constructor(name, age) { // 用于创建和初始化一个由class创建的对象this.name = namethis.age = age}sayHi() {console.log('你好,我是' + this.name)}}class Person2 extends Person1 { // extends 创建子类,Person2是Person1的子类constructor(name, age, sex) {super(name, age) // super() 是用来调用父类的构造函数this.sex = sex // 子类中定义了构造函数,必须先调用 super() 才能使用 this}}let person1 = new Person1('frank', 18)console.log(person1) // person1没有sex,原型上有sayHi这个函数let person2 = new Person2('frank', 18, '男')console.log(person2) // person2有sex,原型中没有sayHi函数
总结:
1、函数声明和类声明的区别
函数声明会提升,类声明不会
首先需要声明你的类,然后访问它,否则像下面的代码会抛出一个ReferenceError
2、ES5继承和ES6继承的区别
- ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.call(this))
- ES6的继承有所不同,实质上是先创建父类的实例对象this,然后再用子类的构造函数修改this。子类没有自己的this对象,所以必须先用
super()调用父类的构造函数,才能使用this,否则新建实例报错。
