[ JavaScript ] JavaScript 实现继承.
对于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 +
以上就是对象继承的一些问题,以记录之,谨防忘记。
最新文章
- 操作系统篇-hello world(免系统运行程序)
- SCNU 2015ACM新生赛初赛【1001~1011】个人解题思路
- js构建ui的统一异常处理方案(四)
- 81.Android之沉浸式状态栏攻略
- 微信开发之Author网页授权
- 20145225唐振远 实验二 ";Java面向对象程序设计";
- 20145218 《Java程序设计》第9周学习总结
- 2层Folder删除问题,父文件夹删不掉
- Oracle笔记 四、增删改、事务
- LInux下socket编程学习笔记
- Programme skills
- bat中的连接符
- Hadoop, Python, and NoSQL lead the pack for big data jobs
- AVL树相关操作
- JVM虚拟机
- Hyperledger Fabric 建立一个简单网络
- 在JS中调用CS里的方法(PageMethods)
- [GPU] DIY for Deep Learning Workstation
- 使用python查询某目录下所有‘jpg’结尾的图片文件
- WP-PostViews使用
热门文章
- (转)Vue 爬坑之路(三)—— 使用 vue-router 跳转页面
- sublime之markdown快捷键
- (转)Arcgis for JS之Cluster聚类分析的实现
- codeforces_731C_[dfs][并查集]
- 零基础学习Linux培训,应该选择哪个培训班?
- isset在php5.6-和php7.0+的一些差异
- Vue项目搭建及原理四
- AIM Tech Round (Div. 2)——ABCD
- [置顶]
 Git学习总结(1)——Git使用详细教程
- poj 1724 最短路+优先队列(两个约束条件)