JavaScript 常用继承方式
-
原型链继承
构造函数,原型,实例之间的关系:每个构造函数之间都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都会包含一个原型对象的指针
function Animal() { this.name = '动物' } Animal.prototype.getName = function() { return this.name } function Dog() { this.age = 2 } Dog.prototype = new Animal() Dog.prototype.getAge = function() { return this.age } const dog = new Dog() console.log(dog.getName()) //动物
缺点:多个实例对引用类型的操作会被篡改,即父类原型上的方法可以被重写
-
借用构造函数继承
function Animal(name) { this.name = name this.getName = function() { return this.name } this.setName = function(name) { return this.name = name } } Animal.prototype.getInfo = function() { return this.name + 'jijijio' } function Dog(age,name) { Animal.call(this,name) this.age = age this.getAge = function() { return this.age } this.setAge = function(age) { this.age = age } } const dog = new Dog(12, '狗狗') const ani = new Animal() // console.log(ani.getInfo()) console.log(dog.name) // error dog.getInfo is not a function
优点:可以给父类传递参数
缺点:1.只能继承父类的实例属性和方法,不能继承原型的属性和方法
2.无法实现复用,每个子类都有父类实例函数的副本,影响性能
-
组合继承
function Animal(name) { this.name = name this.getName = function() { return this.name } } Animal.prototype.setName = function(name) { this.name = name } function Dog(name) { Animal.call(this,name) } Dog.prototype = new Animal() const dog = new Dog('我是继承的狗') console.log(dog) console.log(dog.name) dog.setName('大黄狗') console.log(dog.name)
缺点:使用子类创建对象时,其原型中会存在两份相同的属性和方法
-
ES6
类继承extendsclass Animal{ constructor(name,age){ this.name = name this.age = age } get info() { return this.getInfo() } getInfo(){ return this.name + this.age } } class Dog extends Animal { constructor(name,age,height) { super(name,age) this.height = height } get fullInfo(){ return this.getFullInfo() } getFullInfo(){ return this.name + this.age + this.height } } // const animal = new Animal('dog',12) // console.log(animal.info) const dog = new Dog('big dog',55,180) console.log(dog.fullInfo) console.log(dog)
extends
关键字主要用于类声明或者类表达式中,以创建一个子类。其中constructor
表示构造函数,一个类中只能有一个构造函数。有多个会报错SyntaxError
,如果没有显示的创建则会默认添加constructor
方法