js中的继承是“原型”继承,所谓原型继承是说新对象的父亲是另一个对象,而不是一个类(js中貌似也没有类的概念),就好比科隆一个人,你得到不是一个全新的人,而是一个已经存在的人,他身上的痦子痣子,科隆人身上也都有,而且位置也都一样,总之,科隆人是诞生了,但不是“新”生。
既然要“继承”,总要有“父亲”(即:原型对象)存在的。在js中,你可以通过声明或动态的创建去得到一个新对象。每个对象都会有一个__proto__属性,该属性指向其对象的原型对象。这个属性就像链表中的指针,一个个连起来就构成了“原型链”,这条原型链的头结点是Object.prototype,Object.prototype是所有对象的祖先,而Object是构造函数,每个构造函数由都有一个prototype属性,该属性也是指向原型对象,不过这个对象不是构造函数的原型对象,而是其生成的对象的原型对象(构造函数中的__proto__属性指向该构造函数的原型对象,构造函数的顶级原型对象是Function.prototype)。
看例子:
先通过构造函数来新建一个父对象。
var Person = function(name){
this.name=name;
};
var someone=new Person("zhangsan");
debugger;
console.log(someone.name);
console.log(someone.__proto__ == Person.prototype);
输出:
zhangsan
true
其中,Person.prototype就是someone的原型对象,Person.prototype的原型对象就是Object.prototype
下面在这个Person的基础上新建一个superman,这个superman具有一些超能力。
var SuperMan = function(name,powers){
Person.call(this,name);
this.powers=powers;
};
SuperMan.prototype=new Person;
var sm=new SuperMan('Clark','fly');
console.log(sm.name+" can "+sm.powers);
console.log(sm.__proto__);
console.log(SuperMan.prototype);
输出:
Clark can fly
Person
Person
这样虽然是原型继承,但看起来不明显,如果zhangsan会飞的话,看起来就明显了。
var Person = function(name){
this.name=name;
};
var someone=new Person("zhangsan");
var SuperMan = function(powers){
this.powers=powers;
};
SuperMan.prototype=someone;
var sm=new SuperMan('fly');
console.log(sm.name+" can "+sm.powers);
console.log(sm.__proto__);
console.log(SuperMan.prototype);
输出:
zhangsan can fly
Person
Person
附一张《Node.js开发指南》上的一幅图
两篇必看的文章: