javascript之对象(二)&& 继承问题
JavaScript的继承本质上是通过原型链来实现的,主要的模式有如下
1 原型链模式
//思想是根据每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型的内部指针。 //问题是在于所有的实例都会共享同一份父类对象,因为所有子类的prototype只有一份,而也只有这一份去实例化了一个父类对象。也正是因为如此,造成子类不能给超类对象传参,因为这样会直接修改了这一份父类的实例。 function SuperType() { this.property = false; } SuperType.prototype.getSuperValue = function() { return this.property; } function SubType() { this.property = true; } SubType.prototype = new SuperType(); //实现所在,也是问题所在 SubType.prototype.getSubValue = function() { return this.property; }
2 借用构造函数
//在子类构造函数的内部调用超类的构造函数,函数不过是在特定函数中执行代码的对象,可以通过使用call()和apply()来实用。 //这样做解决了传参的问题,因为每一个子类都对应一个父类对象了,但这样会出现函数复用的问题。 function SuperType() { this.color = ["red", "blue", "green"]; } function SubType() { SuperType.call(this); //实现所在,也是问题所在 }
3 组合继承
//使用原型链实现对原型属性和方法的继承(因为只有一份实例),使用借用构造函数来实现对实例属性的继承。 //问题主要在于会调用两次父类的构造函数,一次是在创建子类弄原型的时间,一次是在子类型构造函数内部,这样会导致父类实例变量有两份,一份在子类中,一份子类的原型中。 function SuperType(name) { this.name = name; } SuperType.prototype.sayName = function() { alert(this.name); }; function SubType(name, age) { SuberType.call(this, name); //调用一次 this.age = age; } SubType.prototype = new SuperType(); //第二次
4 寄生组合式继承
//只是继承了原型 function object(o) { function F(){} F.prototype = o; return new F(); } function inheritPrototype(subType, superType) { var prototype = object(superType.prototype); //创建对象 prototype.constructor = subType; //增强对象 subType.prototype = prototype; //指定对象 } function SuperType(name) { this.name = name; } SuperType.prototype.sayName = function() { alert(this.name); }; function SubType(name, age) { SuberType.call(this, name); //调用一次 this.age = age; } //SubType.prototype = new SuperType(); //第二次 inheritPrototype(subType, SuperType);