对于javascript中的继承,因为js中没有后端语言中的类式继承。所以js中的继承,一般都是原型继承(prototype)。

function P (name){
this.name = name;
this.say = function(){
console.log('p');
}
} function S (name,id){
this.id = id; this.eat = function(){
console.log('s');
}
} S.prototype = P.prototype; var s = new S();

以上代代码存在一个重要问题:

S.prototype = P.prototype;

该句代码会导致,在改动子类的prototype的时候,相同会影响父类的prototype元素。

解决方案一般採用new 父级对象的方式:

S.prototype = new P();

这里涉及到new 的工作原理,new P(), 会依据P的prototype对象建立一个实例,然后将构造方法中的成员变量和成员方法设置进去。

此种方式, 改动子类的prototype则不会影响父类的prototpye(因为是新建了一个对象,不再是指向同一个prototype).

设置prototype之后。还须要重置子类S的contrustor,让其重指向 S。而不是new P() 所相应的construstor. 例如以下:

S.prototype.constructor = S;

非常多时候这里不重置。不会出现故障,可是假设后面须要用到constructor 来创建实例,或者判定实例类型,则会出现错误。

所以这里最好是重置。

上面所述的原型继承。尽管能够通过JavaScript原型继承,可是相同存在不足。

此种继承方式。不可以继承在构造方法设置的成员变量和成员方法。仅仅能继承在原型中设置的方法,或者属性。

如:

var s = new S('yang','01');

当中的第一个參数,并不能传递给到name属性。

于是引出另外一种继承方式: 对象冒充。

function P (name){
this.name = name;
this.say = function(){
console.log('p');
}
} function S (name,id){
P.call(this,name);
this.id = id;
this.eat = function(){
console.log('s');
}
} var s = new S('yanghi','test');

在子类构造方法中,借用父类的构造方法。使子类具有父类的属性和方法。

例如以下:

P.call(this,name);

该句代码与例如以下效果一样:

this.name = name;
this.say = function(){}

从而将父类的属性复制到子类中。从而实现对象冒充。

那么该此种对象冒充方式。相同存在问题:

1 无法继承原型prototype中的属性和主法。

2 构造方法的成员方法在父类和子类中都会有一份拷贝,造成内存的添加。

所以最好的实现方式是:

1 对原型对象。採用原型继承

2 构造方法中的属性和方法。採用对象冒充。

这也是当前绝大对数的js继承库所採用的实现方式。例如以下:

function P (name){
this.name = name;
} P.prototype.say = function(){
console.log('say');
} function S (name,id){
P.call(this,name);
this.id = id;
} function Bare(){}
Bare.prototype = P.prototype;
S.prototype = new Bare();
S.prototype.constructor = S; S.prototype.eat = function(){
console.log('eat');
} var s = new S('yanghi','test');

这里的成员属性。採用对象冒充,成员方法採用原型继承。

注意一点。这里实现原型继承须要採用一个中间变量。例如以下:

S.prototype = new Bare();

假设不採用中间变量。直接new P() 的话,会出现故障。

因为new 会依照P的prototype对象模版,创建一个对象,这一步没有问题。

可是接下来。它会将P构造方法的成员属性也设置到这个对象中,就会导致对这个对象污染。

这里我们仅仅须要它的prototype就能够了。其他的成员变量採用对象冒充的方式就能够了。

第三种实现继承方式,採用ES5 Object.create实现。

//Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
} Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info("Shape moved.");
}; // Rectangle - subclass
function Rectangle() {
Shape.call(this); //call super constructor.
} Rectangle.prototype = Object.create(Shape.prototype); var rect = new Rectangle(); rect instanceof Rectangle //true.
rect instanceof Shape //true. rect.move(1, 1); //Outputs, "Shape moved."

只是此方式最大的问题还是兼容性,须要 IE 9 + , safari 5 +,opera 11.6 +

以上就是对象继承的一些问题,以记录之,谨防忘记。

最新文章

  1. 操作系统篇-hello world(免系统运行程序)
  2. SCNU 2015ACM新生赛初赛【1001~1011】个人解题思路
  3. js构建ui的统一异常处理方案(四)
  4. 81.Android之沉浸式状态栏攻略
  5. 微信开发之Author网页授权
  6. 20145225唐振远 实验二 "Java面向对象程序设计"
  7. 20145218 《Java程序设计》第9周学习总结
  8. 2层Folder删除问题,父文件夹删不掉
  9. Oracle笔记 四、增删改、事务
  10. LInux下socket编程学习笔记
  11. Programme skills
  12. bat中的连接符
  13. Hadoop, Python, and NoSQL lead the pack for big data jobs
  14. AVL树相关操作
  15. JVM虚拟机
  16. Hyperledger Fabric 建立一个简单网络
  17. 在JS中调用CS里的方法(PageMethods)
  18. [GPU] DIY for Deep Learning Workstation
  19. 使用python查询某目录下所有‘jpg’结尾的图片文件
  20. WP-PostViews使用

热门文章

  1. (转)Vue 爬坑之路(三)—— 使用 vue-router 跳转页面
  2. sublime之markdown快捷键
  3. (转)Arcgis for JS之Cluster聚类分析的实现
  4. codeforces_731C_[dfs][并查集]
  5. 零基础学习Linux培训,应该选择哪个培训班?
  6. isset在php5.6-和php7.0+的一些差异
  7. Vue项目搭建及原理四
  8. AIM Tech Round (Div. 2)——ABCD
  9. [置顶] Git学习总结(1)——Git使用详细教程
  10. poj 1724 最短路+优先队列(两个约束条件)