继承
通常利用原型链实现继承。
ES5 继承
常见的一种是“借用构造函数”,例如:
function Person (a, b) {
this.a = a;
this.b = b;
}
Person.prototype.getA = function(){
return this.a;
}
function Sub (a, b) {
// 执行 Persion,让其内部的 this 指向 Sub 的实例
Person.call(this, a, b);
}
// 把 Sub 的原型指向 Person 的实例,这样 Sub 就可以用到 Person 原型上的属性或方法了
Sub.prototype = new Person;
// 把构造函 数改回来
Sub.prototype.constructor = Sub;
这种方式会调用 Person 函数两次,另一种常用的方式是“寄生组合式”继承。通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。例如:
function Person (a, b) {
this.a = a;
this.b = b;
}
Person.prototype.getA = function(){
return this.a;
}
function Sub (a, b) {
Person.call(this, a, b);
}
// 专门用于继承的函数
function inherit (P, C) {
// P 是父类,C 是子类
// 调用 create 方法后,prototype.__proto__ === P.prototype
var prototype = Object.create(P.prototype);
prototype.constructor = C;
C.prototype = prototype;
}
inherit(Person, Sub);
// Sub 的实例对象的 __proto__ 是 Sub.prototype;
// 而 Sub.prototype 是空的,它只有一个 constructor,指向 Sub;
// Sub.prototype.__proto__ 指向 P.prototype
ES6 继承
class Super{
constructor(age, gender) {
this.age = age;
this.gender = gender;
}
sayAge() {
return this.age;
}
}
class Sub extends Super{
constructor(name, age, gender) {
this.name = name;
super(age, gender);
}
sayName() {
return this.name;
}
}
判断属性是否是继承而来
在 js 对象中,使用对象里的某个属性或者方法时,这个属性或者方法不一定存在于这个对象当中,也可能是继承来的。例如:
var obj = {}; // 该对象没有任何属性和方法
console.log(obj.toString()); // 却可以调用 toString 方法
如何判断对象中的某个属性是继承来的?可以利用 in 运算符和 hasOwnProperty 方法来判断。
in运算符可以判断属性是否在指定的对象或其原型链中;hasOwnProperty方法可以判断对象自身属性中是否具有指定的属性;
代码如下:
function isInherit(prop, object){
return prop in object && !object.hasOwnProperty(prop);
}
实现 instanceof
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。例如:
function C(){}
var o = new C();
o instanceof C; // true
o instanceof Object; // true
function D(){}
o instanceof D; // false
实现:
function myInstanceof(object, constructor){
let proto = Object.getPrototypeOf(object);
let prototype = constructor.prototype;
while(true){
// 原型链的最上层是 null
if(proto === null) return false;
if(proto === prototype) return true;
proto = Object.getPrototypeOf(proto);
}
}
getPrototypeOf 方法可以返回指定对象的原型,相当于 object.__proto__。如果没有继承,则返回 null。
Object.prototype.proto === null // true