继承
概念
- JavaScript 对象有一个指向一个原型对象的链。
- 当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
- 实例化的对象, 只能继承构造函数内函数体中设置的属性和方法以及构造函数对应的原型对象(包括原型链)中里的成员
继承的方法
分ES5方法和ES6方法
ES6方法
使用class 语法,可直接定义和 extends 一个类型
"use strict";
class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
// Square继承Polygon
class Square extends Polygon {
constructor(sideLength) {
super(sideLength, sideLength);
}
get area() {
return this.height * this.width;
}
set sideLength(newLength) {
this.height = newLength;
this.width = newLength;
}
}
var square = new Square(2);
ES5方法
- 原型链继承
// 假设有一个需要继承的一个类型 Animal function Cat() {} Cat.prototype = new Animal // 添加一个属性 Cat.prototype.name = 'cat'
- 构造继承
继承构造函数内函数体中的属性和方法// 假设有一个需要继承的一个类型 Animal function Cat(name){ Animal.call(this) // 添加一个属性 this.name = name || 'cat' }
- 组合继承
以上两种继承的组合使用
(以下方法可优化内存)function Cat(){ // 继承Animal内函数体中的属性和方法 Animal.call(this) this.name = 'cat' } (function(){ // 创建一个没有实例方法的类 var Super = function () {} Super.prototype = Animal.prototype // 将实例作为子类的原型, 继承Animal的原型 Cat.prototype = new Super() // 添加方法 Cat.prototype.say = function () { // TOOD } })()
- 使用 for in 循环遍历对象的属性时,继承该对象上(包括原型链上)的所有属性
function extend(method,obj){ for( var key in obj){ method.prototype[key]=obj[key]; }; } function Father() { this.a = a } function Son(b) { this.b = b; } const son = new Son() const father = new Father() extend(son,father);
- Object.create()
创建一个新对象。新对象的原型就是调用 create 方法时传入的第一个参数var a = {a: 1}; // a ---> Object.prototype ---> null var b = Object.create(a); // b ---> a ---> Object.prototype ---> null console.log(b.a); // 1 (继承而来) var c = Object.create(b); // c ---> b ---> a ---> Object.prototype ---> null var d = Object.create(null); // d ---> null console.log(d.hasOwnProperty); // undefined, 因为d没有继承Object.prototype