javascript实现继承的几种方式
原型链方式实现继承
- function SuperType(){
- this.property = true;
- this.colors = ['red','blue','green'];
- }
- SuperType.prototype.getSuperValue = function(){
- return this.property;
- };
- function SubType(){
- this.subprototype = false;
- }
- SubType.prototype = new SuperType(); //继承了SuperType
- SubType.prototype.constructor = SubType
- var instance1 = new SubType();
- instance1.colors.push('black');
- console.log("instance1.colors:",instance1.colors,'getSuperValue():',instance1.getSuperValue());
- var instance2 = new SubType();
- console.log("instance1.colors:",instance1.colors,'getSuperValue():',instance1.getSuperValue());
![](http://static.blog.csdn.net/images/save_snippets.png)
function SuperType(){
this.property = true;
this.colors = ['red','blue','green'];
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}; function SubType(){
this.subprototype = false;
}
SubType.prototype = new SuperType(); //继承了SuperType
SubType.prototype.constructor = SubType var instance1 = new SubType();
instance1.colors.push('black');
console.log("instance1.colors:",instance1.colors,'getSuperValue():',instance1.getSuperValue()); var instance2 = new SubType();
console.log("instance1.colors:",instance1.colors,'getSuperValue():',instance1.getSuperValue());
原型链的问题
借用构造函数方式实现继承
- function SuperType(name){
- this.colors = ['red','blue','grezen'];
- this.name = name;
- this.print = function(obj){
- console.log("print:",obj);
- }
- }
- SuperType.prototype.getName = function(){
- return this.name;
- }
- function SubType(name,age){
- SuperType.call(this,name);
- this.age = age;
- }
- var instance1 = new SubType('zxy',24);
- instance1.colors.push('baclk');
- console.log('instance1.name:',instance1.name,'instance1.age:',instance1.age);
- var instance2 = new SubType('ABC',111);
- console.log('instance2.name:',instance2.name,'instance2.age:',instance2.age,'instance2.colors:',instance2.colors);
- instance2.print(instance2.colors);
![](http://static.blog.csdn.net/images/save_snippets.png)
function SuperType(name){
this.colors = ['red','blue','grezen'];
this.name = name;
this.print = function(obj){
console.log("print:",obj);
}
}
SuperType.prototype.getName = function(){
return this.name;
} function SubType(name,age){
SuperType.call(this,name);
this.age = age;
} var instance1 = new SubType('zxy',24);
instance1.colors.push('baclk');
console.log('instance1.name:',instance1.name,'instance1.age:',instance1.age); var instance2 = new SubType('ABC',111);
console.log('instance2.name:',instance2.name,'instance2.age:',instance2.age,'instance2.colors:',instance2.colors);
instance2.print(instance2.colors);
SuperType.call(this, name);会在新对象(指的是SubType的实例)上执行SuperType()函数中定义的所有代码初始化。结果SubType()的每个实例都有一个自己的colors属性的副本了。(解决了原型中包含引用类型值得问题)
借用构造函数存在的问题
组合继承
- function SuperType(name){
- this.name = name;
- this.colors = ['red','blue','green'];
- }
- SuperType.prototype.getName = function(){
- return this.name;
- }
- function SubType(name,age){
- SuperType.call(this,name);
- this.age = age;
- }
- SubType.prototype = new SuperType();
- SubType.prototype.constructor = SubType;
- SubType.prototype.getAge = function(){
- return this.age;
- }
- var instance1 = new SubType('zxy',24);
- instance1.colors.push('black');
- console.log('colors:',instance1.colors);
- console.log('instance1.getName():',instance1.getName(),'instance1.getAge():',instance1.getAge());
- var instance2 = new SubType('zxy',24);
- console.log('colors:',instance2.colors);
- console.log('instance2.getName():',instance2.getName(),'instance2.getAge():',instance2.getAge());
![](http://static.blog.csdn.net/images/save_snippets.png)
function SuperType(name){
this.name = name;
this.colors = ['red','blue','green'];
}
SuperType.prototype.getName = function(){
return this.name;
} function SubType(name,age){
SuperType.call(this,name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.getAge = function(){
return this.age;
} var instance1 = new SubType('zxy',24);
instance1.colors.push('black');
console.log('colors:',instance1.colors);
console.log('instance1.getName():',instance1.getName(),'instance1.getAge():',instance1.getAge()); var instance2 = new SubType('zxy',24);
console.log('colors:',instance2.colors);
console.log('instance2.getName():',instance2.getName(),'instance2.getAge():',instance2.getAge());
组合继承避免了原型链和借用构造函数技术的缺陷,融合了它们的优点,成为JavaScript中最常用的继承模式。而且instanceof和isPrototypeOf()也能够用于基于组合模式创建的对象。
原型式继承
- function object(o){
- function F(){}
- F.prototype = o;
- return new new F();
- }
![](http://static.blog.csdn.net/images/save_snippets.png)
function object(o){
function F(){}
F.prototype = o;
return new new F();
}
在object()函数内部,先创建了一个临时性的构造函数F(),然后将传入的对象作为这个构造函数的原型,最后返回这个这个临时类型的新实例。从本质上来讲,object对传入的其中的对象执行了一次浅复制。我们看下面的例子:
- var person = {
- name:'zxy',
- friends: ['A','B','C']
- };
- var person1 = object(person);
- person1.name = 'zxy person1';
- person1.friends.push('D');
- console.log(person1);
- var person2 = object(person);
- person2.name = 'zxy person2';
- console.log(person2);
![](http://static.blog.csdn.net/images/save_snippets.png)
var person = {
name:'zxy',
friends: ['A','B','C']
}; var person1 = object(person);
person1.name = 'zxy person1';
person1.friends.push('D');
console.log(person1); var person2 = object(person);
person2.name = 'zxy person2';
console.log(person2);
克罗克福德主张的这种原型式继承,要求你必须有一个对象可以作为另一个对象的基础。如果有这么一个对象的话,就把它传递给object()函数,然后在根据需要在对得到的对象加已修改。在上面的例子中,可以最为基础对象的是person,于是我们把它出入object()中,然后object()函数返回一个新对象,这个新对象将person对象作为原型,所以它的原型中包含一个基本类型值和一个引用类型值。这就意味着person.fridends不仅属于pserson所有,而且也会被person1和person2共享。实际上,相当于创建了person的两个副本(浅复制)。原型式继承和原型链技术实现继承存在同样的问题。
原型式继承的问题
不过别忘了,原型式继承和原型模式技术实现继承存在同样的问题。原型包含引用类型的值,通过一个实例对这个引用类型修改,会在其它实例反映出来。
寄生式继承
- function object(o){
- function F(){}
- F.prototype = o;
- return new F();
- }
- function createAnother(o){
- var clone = object(o);//通过调用函数创建一个新对象
- clone.sayHi = function(){//通过给新对象新增方法来增强这个对象
- console.log('HI 小明..');
- }
- return clone; //返回这个对象
- }
![](http://static.blog.csdn.net/images/save_snippets.png)
function object(o){
function F(){}
F.prototype = o;
return new F();
} function createAnother(o){
var clone = object(o);//通过调用函数创建一个新对象
clone.sayHi = function(){//通过给新对象新增方法来增强这个对象
console.log('HI 小明..');
}
return clone; //返回这个对象
}
在这个例子中,createAnother()函数接受一个参数,就是将要作为新对象的基础(原型)对象。然后把这个对象(o)传递给object()函数,将返回值赋给clone。在为clone对象添加新方法sayHi(),最后返回clone。可以像下面这样使用createAnother()函数:
- var person = {
- name:'zxy',
- friends: ['A','B','C']
- };
- var anotherPerson = createAnother(person);
- anotherPerson.sayHi();
![](http://static.blog.csdn.net/images/save_snippets.png)
var person = {
name:'zxy',
friends: ['A','B','C']
}; var anotherPerson = createAnother(person);
anotherPerson.sayHi();
这个例子中的代码,基于person对象返回了一个新对象anotherPerson.新对象不仅具有person的所有属性和方法。而且还有自定义的sayHi()方法。
寄生组合模式
- //超类
- function SuperType(name){
- this.name = name;
- this.colors = ['red','blue','green'];
- }
- SuperType.prototype.getName = function(){
- return this.name;
- }
- //子类
- function SubType(name,age){
- SuperType.call(this,name);//第二次调用超类构造函数
- this.age = age;
- }
- SubType.prototype = new SuperType(); //第一次调用超类构造函数
- SubType.prototype.constructor = SubType;
- SubType.prototype.getAge = function(){
- return this.age;
- }
- //创建SubType()构造函数的一个实例
- var instance = new SubType('zxy',24);
- console.log(instance); //输出类instance的原型链(见图IMG-1)
![](http://static.blog.csdn.net/images/save_snippets.png)
//超类
function SuperType(name){
this.name = name;
this.colors = ['red','blue','green'];
}
SuperType.prototype.getName = function(){
return this.name;
} //子类
function SubType(name,age){
SuperType.call(this,name);//第二次调用超类构造函数
this.age = age;
}
SubType.prototype = new SuperType(); //第一次调用超类构造函数
SubType.prototype.constructor = SubType;
SubType.prototype.getAge = function(){
return this.age;
} //创建SubType()构造函数的一个实例
var instance = new SubType('zxy',24); console.log(instance); //输出类instance的原型链(见图IMG-1)
- function object(o){
- function F(){};
- F.prototype = o;
- return new F();
- }
- function inheritPrototype(subType,superType){
- var prototype = object(superType.prototype); //以superType.prototype为基础创建一个新对象(原型式继承).
- //注意这里是浅复制,尽量避免将colorsPrototype这样的属性定义在原型对象中,应该像colors属性定义在构造函数内部
- //subType.prototype = prototype;
- //subType.prototype.constructor = c;
- prototype.constructor = subType; //给prototype对象添加constructor属性,增强对象(寄生式继承)
- subType.prototype = prototype; //将prototype对象子类的原型对象
- }
![](http://static.blog.csdn.net/images/save_snippets.png)
function object(o){
function F(){};
F.prototype = o;
return new F();
} function inheritPrototype(subType,superType){
var prototype = object(superType.prototype); //以superType.prototype为基础创建一个新对象(原型式继承).
//注意这里是浅复制,尽量避免将colorsPrototype这样的属性定义在原型对象中,应该像colors属性定义在构造函数内部
//subType.prototype = prototype;
//subType.prototype.constructor = c;
prototype.constructor = subType; //给prototype对象添加constructor属性,增强对象(寄生式继承)
subType.prototype = prototype; //将prototype对象子类的原型对象 }
这个实例中的inheritPrototype()函数实现了寄生组合式继承的最简单形式。这个函数接收两个参数:第一个参数是子类构造函数和超类构造函数。在函数内部,第一步是创建超类原型的一个副本。第二部是添加一个constructor属性,从而弥补重写原型而失去的默认的constructor属性。最后一步将新创建的对象(即父类原型的副本)赋给子类的原型。这样,我们可以调用inheritPrototype()函数来替换前边例子中为子类原型赋值的语句了。实例如下:
- //也可以将object()和inheritPrototye()功能合并成一个函数
- /*function inheritPrototype1(subType, superType){
- function F(){};
- F.prototype = superType.prototype;
- subType.prototype = new F();
- subType.prototype.constructor = subType;
- }*/
- //父类
- function SuperType(name){
- this.name = name;
- this.colors = ['red','green','black'];
- }
- SuperType.prototype.sayName = function(){
- console.log("sayName():"+this.name);
- };
- SuperType.prototype.colorsPtototype = ['A','B'];
- //子类
- function SubType(name,age){
- SuperType.call(this,name);
- this.age = age;
- }
- inheritPrototype(SubType,SuperType); //使SubType继承SuperType
- //SubType.prototype = new SuperType(); //SubType.prototype.constructor = SubType; //以前的写法
- SubType.prototype.sayAge = function(){
- console.log("sayName():"+this.age);
- }
- var subType1 = new SubType('zxy','20');
- subType1.sayName();
- subType1.sayAge();
- subType1.colorsPtototype.push('C');
- console.log("colorsPtototype:"+subType1.colorsPtototype);
- console.log("subType1:",subType1);
- var subType2 = new SubType();
- console.log("colorsPtototype:"+subType2.colorsPtototype);
- console.log("subType2",subType2);
![](http://static.blog.csdn.net/images/save_snippets.png)
//也可以将object()和inheritPrototye()功能合并成一个函数
/*function inheritPrototype1(subType, superType){
function F(){};
F.prototype = superType.prototype;
subType.prototype = new F();
subType.prototype.constructor = subType;
}*/ //父类
function SuperType(name){
this.name = name;
this.colors = ['red','green','black'];
}
SuperType.prototype.sayName = function(){
console.log("sayName():"+this.name);
};
SuperType.prototype.colorsPtototype = ['A','B']; //子类
function SubType(name,age){
SuperType.call(this,name);
this.age = age;
}
inheritPrototype(SubType,SuperType); //使SubType继承SuperType
//SubType.prototype = new SuperType(); //SubType.prototype.constructor = SubType; //以前的写法
SubType.prototype.sayAge = function(){
console.log("sayName():"+this.age);
} var subType1 = new SubType('zxy','20');
subType1.sayName();
subType1.sayAge();
subType1.colorsPtototype.push('C');
console.log("colorsPtototype:"+subType1.colorsPtototype);
console.log("subType1:",subType1); var subType2 = new SubType();
console.log("colorsPtototype:"+subType2.colorsPtototype);
console.log("subType2",subType2);
这个例子的高效体现在他只调用一次父类(SubType)的构造函数,并且因此避免了在子类的原型(SubType.prototype)上创建不必要、多余的属性。 与此同时,原型链还能保持不变;因此能够正常使用instanceof和isPrototypeOf()。
javascript实现继承的几种方式的更多相关文章
- 实现JavaScript中继承的三种方式
在JavaScript中,继承可以通过三种手法实现原型链继承 使用apply.call方法 对象实例间的继承. 一.原型链继承 在原型链继承方面,JavaScript与java.c#等语言类似 ...
- javascript实现继承的三种方式
一.原型链继承 function Parent(){} function Child(){} Child.prototype = new Parent(); 通过对象child的prototype属 ...
- JavaScript——实现继承的几种方式
实现继承的6中方法: 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承 拷贝继承 1. 借用构造函数 在子类型构造函数的内部调用超类构造函数.通过使用apply()和call()方法在新 ...
- javascript实现继承的一种方式
function extend(Child, Parent) { var F = function(){}; F.prototype = Parent.prototype; Child.prototy ...
- javascript实现继承的6种方式
/*1.原型链继承*/ function SuperType() { this.property = true; } SuperType.prototype.getSuperValue = funct ...
- javascript中实现继承的几种方式
javascript中实现继承的几种方式 1.借用构造函数实现继承 function Parent1(){ this.name = "parent1" } function Chi ...
- javascript(js)创建对象的模式与继承的几种方式
1.js创建对象的几种方式 工厂模式 为什么会产生工厂模式,原因是使用同一个接口创建很多对象,会产生大量的重复代码,为了解决这个问题,产生了工厂模式. function createPerson(na ...
- 前端知识体系:JavaScript基础-原型和原型链-实现继承的几种方式以及他们的优缺点
实现继承的几种方式以及他们的优缺点(参考文档1.参考文档2.参考文档3) 要搞懂JS继承,我们首先要理解原型链:每一个实例对象都有一个__proto__属性(隐式原型),在js内部用来查找原型链:每一 ...
- javascript创建类的6种方式
javascript创建类的7种方式 一 使用字面量创建 1.1 示例 var obj={}; 1.2 使用场景 比较适用于临时构建一个对象,且不关注该对象的类型,只用于临时封装一次数据,且不适合代码 ...
随机推荐
- js/jsp清空表单2种方法
js方式清空表单数据的两种方式 方法1:遍历页面元素 /* 清空FORM表单内容 id:表单ID*/ function ClearForm(id) { var objId = docume ...
- JavaWeb学习记录(五)——Servlet随机产生验证码
随机产生验证码的工具类: import java.awt.Color;import java.awt.Graphics;import java.awt.image.BufferedImage;impo ...
- 正确答案 全国信息学奥林匹克联赛( ( NOIP2014) 复 赛 模拟题 Day1 长乐一中
[题目描述]小 H 与小 Y 刚刚参加完 UOIP 外卡组的初赛,就迫不及待的跑出考场对答案."吔,我的答案和你都不一样!",小 Y 说道,"我们去找神犇们问答案吧&qu ...
- URAL 1056 Computer Net(最短路)
Computer Net Time limit: 2.0 secondMemory limit: 64 MB Background Computer net is created by consecu ...
- poj1128 拓扑序(DFS)
题意:给出一张图,它是由一系列字母框按一定顺序从下到上摆放,因此上面的字母框会覆盖一部分下面的字母框,确保每个字母框的四条边都至少会出现一个点,要求输出所有可行的摆放顺序,字典序从小到大输出. 首先可 ...
- 磁盘参数修订[转自vbird]
某些时刻,你可能会希望修改一下目前文件系统的一些相关信息,举例来说,你可能要修改 Label name , 或者是 journal 的参数,或者是其他硬盘运行时的相关参数 (例如 DMA 启动与否-) ...
- windows下多个python版本共存
方法/步骤 首先当然是安装你需要的两个不同版本的python,这里我安装的是2.7和3.3的,两个版本安装顺序无所谓. 接下来就是检查环境变量,缺少的我们需要添加.先找到环境变量的位置. ...
- lucene文件格式待整理
这是之前Lucene3.0生成的索引格式 a表
- 【Unity3D基础教程】给初学者看的Unity教程(六):理解Unity的新GUI系统(UGUI)
作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! 理解UGUI的基础架构 UGUI是Unity在4 ...
- maxscript,执行选中代码片段
选中一行或几行代码,然后按数字小键盘上的Enter键,即可单独运行之.此法方便调试.