JavaScript继承
栏目: JavaScript · 发布时间: 6年前
内容简介:原型链继承的原理如期名,是利用创建父类(SuperType)的实例,并将该实例赋值给子类(SubType).prototype实现的,实质是重写子类的原型对象。原型链继承特点:借用构造函数继承(constructor stealing),该继承思想很简单,即在子类型构造函数的内部调用超类型构造函数即可。通过call()方法(或apply()方法也可以),实质上是在(未来将要)新创建的SubType实例的环境下调用SuperType构造函数。
原型链继承
function SuperType() {
this.property = true;
}
// 在原型链上定义方法。
SuperType.prototype.getSuperValue = function (){
return this.property;
}
function SubType() {
this.subproperty = false;
}
// 替换SubType原型,达到继承效果。
SubType.prototype = new SuperType();
// 开始写SubType的方法,注:SubType的方法必须写在替换SubType原型语句后
SubType.prototype.getSubValue = function (){
return this.subproperty;
}
var instance = new SubType();
alert(instance.getSuperValue());
原型链继承的原理如期名,是利用创建父类(SuperType)的实例,并将该实例赋值给子类(SubType).prototype实现的,实质是重写子类的原型对象。
原型链继承特点:
- 引用类型值的原型属性会被所有实例共享。
- 在创建子类型的实例时,没办法再不影响所有对象实例的情况下向超类传递参数。
- 即实现 所有属性方法共享,但无法做到属性、方法独享 。
借用构造函数继承
function SuperType() {
this.colors = ['red','blue','green'];
}
function SubType() {
//继承属性
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push('black');
alert(instance1.colors); //red,blue,green,black
var instance2 = new SubType();
alert(instance2.colors); //red,blue,green
借用构造函数继承(constructor stealing),该继承思想很简单,即在子类型构造函数的内部调用超类型构造函数即可。通过call()方法(或apply()方法也可以),实质上是在(未来将要)新创建的SubType实例的环境下调用SuperType构造函数。
借用构造函数继承特点:
- 可以在子类型构造函数中向超类型构造函数传递参数。
- 方法都在构造函数中定义,无法实现函数复用。
- 超类型的原型中定义的方法对子类不可见。
- 即实现 所有属性独享,但无法做到方法继承 。
组合继承
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); //第二次调用SuperType
this.age = age;
}
//继承方法
SubType.prototype = new SuperType(); //第一次调用SuperType
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
}
var instance1 = new SubType('Y',21);
instance1.colors.push('black');
alert(instance1.colors); //red,blue,green,black
instance1.sayName(); //Y
instance1.sayAge(); //21
var instance2 = new SubType('Z',22);
alert(instance2.colors); //red,blue,green
instance2.sayName(); //Z
instance2.sayAge(); //22
组合继承(combination inheritance)又叫伪经典继承,是JavaScript中最常用的继承模式。组合继承指的是将原型链继承和借用构造函数继承的技术组合到一块,从而发挥二者之长的一种继承模式。该模式通过借用构造函数继承属性,通过重新子类型prototype继承方法。
组合继承特点:
- 实现了 所有方法共享,属性独享 。
- instanceof()和isprototypeOf()能够识别基于组合继承创建的对象。
- 实现的时候调用了两次超类(父类),产生多余属性。
原型式继承
// 工具函数,实质是对传入的对象执行一次浅拷贝。
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
var person = {
name:'Y',
friends:['S','C','V'],
say:function () {
alert(this.friends);
}
};
var anotherPerson = object(person);
anotherPerson.name = 'G';
anotherPerson.friends.push('R');
var yetAnotherPerson = object(person);
yetAnotherPerson.name = 'L';
yetAnotherPerson.friends.push('B');
person.friends.push('my');
anotherPerson.say(); //S,C,V,R,B,my
alert(person.friends); //S,C,V,R,B,my
原型式继承是由道格拉斯·克罗克福德提出的,该模式要求你必须有一个对象可以作为另外一个对象的基础。该模式将一个对象传递给object()函数,然后再根据具体需求对得到的对象加以修改即可。
原型式继承特点:
- 以传入object的对象为原型,拷贝一个副本并反回。
- 做不到函数复用,导致效率低。
- 对象的引用类型所有实例共享 (person的引用类型friends不仅属于person所有,而且也会被antherPerson和yetAnotherPerson共享)。
寄生式继承
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
function createAnother(original) {
var clone = object(original);
clone.sayHi = function (){
alert(this.friends);
};
return clone;
}
var person = {
name:'Y',
friends:['S','C','V']
};
var anotherPerson = createAnother(person);
anotherPerson.friends.push('test');
anotherPerson.sayHi();
var anotherPerson2 = createAnother(person);
anotherPerson2.sayHi();
寄生式继承(parasitic)同样是由克罗克福德提出并推广而之的。该模式创建一个仅用于封装继承过程的函数,该函数的内部以某种方式增强对象,最后再像真地式它做了所有工作一样返回对象。
寄生式继承特点:
- 做不到函数复用,导致效率低。
- 对象的引用类型所有实例共享 。
寄生组合式继承
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
// 将超类型的prototype浅拷贝一遍并赋值给子类型的prototype
// (相当于利用超类型prototype重写子类型prototype以达到继承效果)
function inheritPrototype(subType,superType) {
var prototype = object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
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;
}
//继承方法
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function(){
alert(this.age);
}
var instance1 = new SubType('Y',21);
instance1.colors.push('black');
alert(instance1.colors); //red,blue,green,black
instance1.sayName(); //Y
instance1.sayAge(); //21
var instance2 = new SubType('Z',22);
alert(instance2.colors); //red,blue,green
instance2.sayName(); //Z
instance2.sayAge(); //22
原理如图:
寄生组合式继承解决了组合继承最大的问题——无论什么情况下,都会调用两次超类型构造函数。该模式思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需的无非就是超类型原型的副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。
寄生组合式继承特点:
- 实现了 所有方法共享,属性独享 。
- instanceof()和isprototypeOf()能够识别基于组合继承创建的对象。
参考自《JavaScript高级程序设计》
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 028.Python面向对象继承(单继承,多继承,super,菱形继承)
- PHP类继承、接口继承关系概述
- 面向对象:理解 Python 类的单继承与多继承
- java入门第二季--继承--java中的继承初始化顺序
- 前端基本功(七):javascript中的继承(原型、原型链、继承的实现方式)
- 组合还是继承,这是一个问题?——由模式谈面向对象的原则之多用组合、少用继承
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
第二曲线:跨越“S型曲线”的二次增长
[英]查尔斯·汉迪(Charles Handy) / 苗青 / 机械工业出版社 / 2017-6 / 49.00
S型曲线是每个组织和企业在预测未来时一定会参考的工具,一切事物的发展都逃不开S型曲线(“第一曲线”)。 然而,从公司组织、企业治理、市场的变化,到个人职业发展、社会人际关系以及未来的教育与社会价值,多维度地探讨这个世界需要重新以不同的角度来思考问题,不能够总是停留在“第一曲线”的世界。 如果组织和企业能在第一曲线到达巅峰之前,找到带领企业二次腾飞的“第二曲线”,并且第二曲线必须在第一曲......一起来看看 《第二曲线:跨越“S型曲线”的二次增长》 这本书的介绍吧!