面向对象编程 -- 继承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
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
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
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"