function Parent (name) {
this.name = name;
}
var son = new Parent('chris');
// 实例的 contructor 指向实例的构造函数
console.log(son.constructor === Parent); // true
// instanceof 用于验证实例与原型对象的关系
console.log(son instanceof Parent); // true
// isPrototypeOf 用于验证实例与 prototype 对象的关系
console.log(Parent.prototype.isPrototypeOf(son)) // true
// 实例的 __proto__ 指向其构造函数的 prototype 对象
console.log(son.__ptoto__ === Parent.prototype); // true
// __proto__ 是每个对象都有的属性,prototype 属性只有函数才有
假设有如下两个类
function Person () {
this.type = 'human';
}
function Parent (name) {
this.name = name;
}
想要实现 Parent 继承 Person,常见的有以下四种方式:
/* 1. 构造函数绑定 */
function Parent (name){
Person.apply(this, arguments);
this.name = name;
}
/* 2. prototype 模式 */
Parent.prototype = new Person();
// prototype 对象的 contructor 属性应该指向构造函数,
// 上一步使得 Parent.prototype.contructor === Person
// 此后将使 son.prototype === Parent.prototype === Person,造成继承链紊乱,因此需要修正
Parent.prototype.contructor = Parent;
/* 3. 直接继承 prototype */
// 优点:效率高,不用创建实例,节省内存
// 缺点:任何对 Parent.prototype 的修改将直接影响 Person.prototype
// 缺点:Person.prototype.contructor 也被修改(=== Parent)
Parent.prototype = Person.prototype;
Parent.prototype.contructor = Parent;
/* 4. 利用空对象作为中介 */
var F = function () {};
F.prototype = Person.prototype;
Parent.prototype = new F();
Parent.prototype.constructor = Parent;
假设有以下两个对象
var father = {
lastname: 'paul'
};
var son = {
height: 180
};
需要实现 son 对 father 的继承,有以下几种方式:
/* 1. 空函数作中介 */
function object (o) {
var F = function () {};
F.prototype = o;
return new F();
}
var son = object(father);
son.height = 180;
/* 2. 浅拷贝、深拷贝*/
// 逐个将父对象的属性拷贝至子对象
最后,送上知乎用户 @doris 的一图流作为结尾: