面向对象编程 -- 继承1

一、原型链

// ECMA-262 把原型链定义为 ECMAScript 的主要继承方式。


function SuperType() {
  this.property = true;
}
           
SuperType.prototype.getSuperValue = function() {
  return this.property;
};
           
function SubType() {
  this.subproperty = false;
}
           
// 从SuperType继承
SubType.prototype = new SuperType();
           
SubType.prototype.getSubValue = function () {
  return this.subproperty;
};
           
let instance = new SubType();
console.log(instance.getSuperValue());  // true

原型链 01.png

1.默认原型

// 实际上,原型链中还有一环。

// 默认情况下,所有引用类型都继承自 Object , 这也是通过原型链实现的。

// 任何函数的默认原型都是一个 Object 的实例,这意味着这个实例有一个内部指针指向 Object.prototype 。

2.原型与继承关系

// 原型与实例的关系可以通过两种方式来确定。

// 第一种方式是使用 instanceof 操作符

console.log(instance instanceof Object);     // true
console.log(instance instanceof SuperType);  // true
console.log(instance instanceof SubType);    // true

// 确定这种关系的第二种方式是使用 isPrototypeOf() 方法。

console.log(Object.prototype.isPrototypeOf(instance));     // true
console.log(SuperType.prototype.isPrototypeOf(instance));     // true
console.log(SubType.prototype.isPrototypeOf(instance));     // true

原型与继承关系 02.png

3.关于方法

// 子类有时候需要覆盖父类的方法, 或者增加父类没有的方法。

function SuperType() {
  this.property = true;
}
           
SuperType.prototype.getSuperValue = function() {
  return this.property;
};
           
function SubType() {
  this.subproperty = false;
}
           
// 继承 SuperType
SubType.prototype = new SuperType();
           
// 新方法
SubType.prototype.getSubValue = function () {
  return this.subproperty;
};
           
// 覆盖已有的方法
SubType.prototype.getSuperValue = function () {
  return false;
};
           
let instance = new SubType();
console.log(instance.getSuperValue());   // false

关于方法 03.png

4.原型链的问题

// 原型链虽然是实现继承的强大工具,但它也有问题。

// 只要问题出现在原型中包含引用值的时候。

function SuperType() {
  this.colors = ["red", "blue", "green"];
}
           
function SubType() {}
           
// 继承 SuperType
SubType.prototype = new SuperType();
           
let instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);  // "red,blue,green,black"
           
let instance2 = new SubType();
console.log(instance2.colors);  // "red,blue,green,black" 

原型链的问题 04.png