JavaScript中继承的实现

304 阅读2分钟

有如下题目

  1. 写出一个构造函数 Animal
  • 输入为空
  • 输出为一个新对象,该对象的共有属性为 {行动: function(){}},没有自有属性
  1. 再写出一个构造函数 Human
  • Human 继承 Animal
  • 输入为一个对象,如 {name: 'Frank', birthday: '2000-10-10'}
  • 输出为一个新对象,该对象自有的属性有 name 和 birthday,共有的属性有物种(人类)、行动和使用工具
  1. 再写出一个构造函数 Asian
  • Asian 继承 Human
  • 输入为一个对象,如 {city: '北京', name: 'Frank', birthday: '2000-10-10' }
  • 输出为一个新对象,改对象自有的属性有 name city 和 bitrhday,共有的属性有物种、行动和使用工具和肤色

ES5里的继承,原型链实现继承

function Animal () {	
}

Animal.prototype.action = function () {}

function Human (obj = {}) {
	this.name = obj.name
	this.birthday = obj.birthday
}

Human.prototype = Object.create(Animal.prototype) // 这个写法只会拿到其原型上的属性
// Human.prototype = new Animal() // 这个写法会导致私有属性重复

Human.prototype.species = 'human being'
Human.prototype.toolUse = ''

function Asian (obj) {
	this.city = obj.city
	this.name = obj.name
	this.birthday = obj.birthday
}

Asian.prototype = Object.create(Human.prototype)
Asian.prototype.color = 'yellow'

let sam = new Asian({city: 'shenzhen', name: 'sam', birthday: '828'})
// 结果,如果使用上面注释一行的代码实现继承,就会导致name和birthday重复
sam
Asian {city: "shenzhen", name: "sam", birthday: "828"}
  birthday: "828"
  city: "shenzhen"
  name: "sam"
  __proto__: Animal
    // birthday: undefined
    color: "yellow"
    // name: undefined
    __proto__: Animal
      species: "human being"
      toolUse: ""
      __proto__: Object

ES6里的继承

类可以通过extends关键字实现继承。类是面向对象里面的一个概念,虽然JS也是面向对象,但在ES6之前并没有类这个概念,在这之前JavaScript的面向对象都是不完备的面向对象。 类的返回值是对象,构造函数的返回值也是对象,所以在ES6之前,类这个概念是通过构造函数来实现。

ECMAScript2015中引入的JavaScript类实质上是JavaScript现有的基于原型的继承的语法糖。类语法不会为JavaScript引入新的面向对象的继承模型。

定义一个类的方法是使用一个类声明。要声明一个类,可以使用带有class关键字的类名。

// 类声明
class rectangle{
	constructor(height,width){
		this.width=width
		this.height=height
	}
}
// 类表达式,类名非必须
let rectangle = class (className) {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }

函数声明和类的声明之间的一个重要区别是函数声明会提升,类声明不会,所以需要先声明再访问。

构造函数、静态方法、原型方法、getter、setter、父类、子类,这些名词是类这一概念中术语。

据此来实现前面提到的继承题目如下:

class Animal {
	action () {console.log('行动')}
}

class Human extends Animal {
	constructor (params) {
                super()
		this.name = params.name
		this.birth = params.birth
	}
	species () {return '人类'}
	toolUse () {return '工具'}
}

class Asian extends Human {
	constructor (params) {
		super(params)
		this.city = params.city
	}
	color () {return '肤色'}
}