JavaScript继承

继承

原型链

原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针

原型中有构造函数,指向类

组合继承

function SuperType(name) {    this.name = name;    this.color = ["red", "blue", "green"];}SuperType.prototype.sayName = function (){    alert(this.name);};function SubType(name, age){    // 借用构造函数,在子类的构造函数中执行父类构造函数 ,继承属性 两次调用超类构造函数    SuperType.call(this, name);    this.age = age;}//继承父类方法 一次调用超类构造函数SubType.prototype = new SuperType();//执行上面的方法后constructor指向的是SuperType,需要改回来SubType.prototype.constructor = SubType;SubType.prototype.sayAge = function (){    alert(this.age);};

组合继承避免了原型链和借用构造函数的缺点,融合了他们的优点,成为JavaScript中最常用的继承模式

原型继承模式

//原型式继承function object(o) {    function F() {    }    F.prototype = o;    return new F();}var person = {    name: "Nicholas",    friends: ["Shelby", "Court", "Van"]};var anotherPerson = object(person);anotherPerson.name = "Greg";anotherPerson.friends.push("Rob");var yetAnotherPerson = object(person);yetAnotherPerson.name = "Linda";yetAnotherPerson.friends.push("Barbie");alert(person.friends);

ECMAScript5新增Object.create()方法规范化了原型式继承。

//ECMAScript5新增Object.create()方法规范化了原型式继承。var person = {    name: "Nicholas",    friends: ["Shelby", "Court", "Van"]};var anotherPerson = Object.create(person)

Object.create()方法的第二个参数与Object.defineProperties()方法的第二个参数相同:每个属性都是通过自己的描述符定义的。以这种方式指定的任何属性都会覆盖原型对象上相同属性(只是覆盖不是失效和下面有区别)。

var person = {    name: "Nicholas",    friends: ["Shelby", "Court", "Van"]};var anotherPerson = Object.create(person,{    name: {        value: "Greg"    }});alert(person.name);//"Greg"

PS:happy:: 原型中使用字面量添加方法会导致,原来的原型失效

SubType.prototype = new SuperType();//下面代码会导致上面的失效SubType.prototype = {	getSubValue: function(){		return this.subProperty;	},	otherMethod: function(){		return false;	}}

寄生式模式

和工厂模式类似,仅创建一个封装继承过程的函数

//寄生式模式function createAnother(original){    var clone = object(original);    clone.sayHi = function(){        alert("hi");    };    return clone;}var person = {    name: "Nicholas",    friends: ["Shelby", "Court", "Van"]};var anotherPerson = createAnother(person)anotherPerson.sayHi();

寄生组合式继承

组合继承是最常用的,但是他的不足是无论什么情况下都要调用两次超类构造函数:一次是在创建子类型原型的时候,一次是在子类型构造函数内部;

function SuperType(name) {    this.name = name;    this.colors = ["red", "blue", "green"];}SuperType.prototype.sayName = function () {    alert(this.name);     // 第二次};function SubType(name, age) {    SuperType.call(this, name);    this.age = age;}SubType.prototype = new SuperType();SubType.prototype.constructor = SubType; // 第一次SubType.prototype.sayAge = function (){    alert(this.age);};