大鳄鱼吐血三个月整理的几百GB资源免费分享! ....>>>
开门见山,下面根据继承方式的不同一一介绍:
基于原型链的方法
根据js中prototype的特点这应该是最简单的继承了
var SuperType = function() { this.property= true;
}
SuperType.prototype.getSuperValue= function() { return this.property;
} var SubType = function() { this.subproperty = false;
}
SubType.prototype = new SuperType(); // 继承 SubType.prototype.getSubValue = function() { return this.subproperty;
} var instance = new SubType();
alert(instance.getSuperValue()); // true
此时,前面对象的引用关系如下:
JS对象继承应用关系(参考JavaScript中级编程)
因此,如果泛型具有相同的 name 属性, super 的 getter 将返回:
var Sub = function() { this.property = false;
}
Sub.prototype = new SuperType(); var instance = new Sub();
alert(instance.getSuperValue()); // true,返回子类的属性
可见,JS中的泛型属性都会重绘父类,手法的重绘是一样的。 这是因为JS搜索对象的属性是从子对象开始遍历的,如果没有泛型类型则继续搜索父对象。
另外,JS还提供了判断继承关系的技巧:
alert(instance instanceof SubType); // true alert(instance instanceof SuperType); // true alert(instance instanceof Object); // true alert(SubType.prototype.isPrototypeOf(instance)); //true alert(SuperType.prototype.isPrototypeOf(instance)); //true alert(Object.prototype.isPrototypeOf(instance)); //true
使用原型链有一个非常明显的问题,就是子对象共享同一个父对象的属性。 如果是引用类型,有可能改变一个对象,却影响其他对象的数据。
构造函数继承
构造函数的形式继承可以解决共享相同父对象属性的问题,可以引用父对象的有参构造函数:
var SuperType = function(name) { this.name = name; this.colors = ['red', 'yellow'];
} var SubType = function(name) {
SuperType.call(this, name); this.age = 18;
} var subA = new SubType('Lilei'); var subB = new SubType('HanMeimei');
subA.colors.push('blue'); // 修改引用属性 alert(subA.name); // Lilei alert(subA.colors); // 'red,yellow,blue' alert(subB.name); // HanMeimei alert(subB.colors); // 'red,yellow'
与对象创建的情况一样,纯构造函数形式导致每个对象不共享父对象的功能。 于是就有了联合继承的形式,各取本金。
组合继承方法
组合继承是通过原型链继承对象的方式创建javascript对象,构造函数继承对象的属性:
var SuperType = function(name) { this.name = name
}
SuperType.prototype.getName = function() { return this.name
} var SubType = function(name) {
SuperType.call(this, name);
}
SubType.prototype = new SuperType(); var sub = new SubType('Lilei');
alert(sub.getName()); // Lilei
当调用新的子对象时,调用构造函数时会重新定义该对象自身的属性,因此与父对象的属性分离。 而组合继承要求父对象的构造方法也以组合构造的形式定义,否则泛型使用组合继承是没有用的。
通过鞋厂模式创建子对象
下面提供的继承方法见《JS中级编程》。 本书也将它们视为继承方法,但我认为只能算是之前继承方法的鞋厂模式。
原型继承
给我任何原型,并给你他的一个子对象(鞋厂模型......)
// 就是他了
function subInstance(o) {
function F(){}
F.prototype = o; return new F();
}
var superInstance = {
name: 'Lilei' }
var sub = subInstance(superInstance); alert(sub.name); // Lilei
事实上,子对象共享父对象的所有属性。 以复合形式实现子实例? 你可以尝试一下,而且因为是鞋厂模式,考虑到通用性,这并不是一个好的选择。
寄生遗传
如果鞋厂不是那么通用,可以在创建子对象时添加一些额外的属性:
function subInstanceWithAge(o) {
function F(){}
F.prototype = o;
var sub = new F(); sub.age = 18; return sub; }
var superInstance = {
name: 'Lilei' }
var sub = subInstanceWithAge(superInstance); alert(sub.name); // Lilei
alert(sub.age); // 18
它也是共享父对象的属性。
寄生联合遗传
这些传承方式简直就是令人尴尬的症状。
function inherit(subType, superType) { function F() {}
F.prototype = superType.prototype; var sub_prototype = new F();
sub_prototype.constructor = subType;
subType.prototype = sub_prototype;
} var SuperType = function(name) { this.name = name;
}
SuperType.prototype.getName = function() { return this.name;
} var SubType = function(name, age) {
SuperType.call(this, name); this.age = age;
}
inherit(SubType, SuperType);
SubType.prototype.getAge = function() { return this.age;
} var sub = new SubType('Lilei', 18);
alert(sub.getName()); // Lilei alert(sub.getAge()); // 18 alert(SuperType.isPrototypeOf(sub)); // false
虽然子对象可以继承父对象的属性,但是子对象根本不知道父对象。 与其说是继承创建javascript对象,不如说是复制,但它会破坏subType原有的继承解释。
最后介绍的三种鞋厂方式,可以看作是三种传统继承方式的分歧。 其实只要掌握了前三类继承,就可以根据实际需要开发出各种满足自己需求的继承工具技能。
文/WoodsWalker(短书作者)
原文链接: