【前端】JavaScript继承实现的四种方式
转载请注明出处:http://www.cnblogs.com/shamoyuu/p/4770235.html
一、继承的实现方法
1、原型链继承
这个继承最为简单,它的实现原理是,每一个AO对象都有一个prototype,返回对象类型原型的引用,所以可以给它赋值一个对象,就可以实现简单的原型链继承。
function Animal(){
this.eat = function(){
alert("我会吃");
}
} function Bird(){
this.fly = function(){
alert("我会飞");
}
}
//设置Bird类的原型为一个Animal对象
Bird.prototype = new Animal(); var pigeon = new Bird();
pigeon.fly();
pigeon.eat();
结果出现了,实现了鸟类继承动物会吃的特性。打印一下console.info(pigeon)我们可以看到:
当前对象的__proto__属性为一个Animal对象,而eat方法在这个Animal对象也就是它的父类里,如果一个属性或方法在当前对象里无法找到的话,就会照着原型链一步一步找上去。
这里Bird的父类是Animal,Animal的父类是Object,或者说所有没有直接指定prototype的对象,它的父类都是Object。因为toString()方法就是在Object里,所以所有对象都可以调用它。而Object的父类是null。
还有一个需要注意的问题是,原型链继承中,所有的子类的父类对象都是同一个。只要任意一个子类改变了父类对象的属性,那所有对象都会受到影响。这点可能是缺点,也可能是优点。
注:prototype和__proto__的区别可以看我另外一篇博客 http://www.cnblogs.com/shamoyuu/p/prototype.html
2、原型冒充继承
原型冒充的原理是:把父类的构造函数拿过来执行一遍。下面看代码:
function Animal(){
this.eat = function(){
alert("我会吃");
}
} function Bird(){
Animal.apply(this, arguments);this.fly = function(){
alert("我会飞");
}
} var pigeon = new Bird();
pigeon.fly();
pigeon.eat();
效果跟上面是一样一样的,但是这个时候eat方法已经不在原型链上,而是在pigeon对象上。
3、复制继承
复制继承的原理是:把父类所有的属性和方法复制过来。下面看代码。
function Animal(){
this.eat = function(){
alert("我会吃");
}
} function Bird(){
this.fly = function(){
alert("我会飞");
}
//这里写一个继承的方法,用来复制所有父类的属性或方法
this.extend = function(parent){
for(var key in parent){
this[key] = parent[key];
}
}
} var pigeon = new Bird();
//执行继承的方法
pigeon.extend(new Animal()); pigeon.fly();
pigeon.eat();
这个也和上面一样一样的。
4、ES6标准类的继承
ES6中引入了class的概念,新的class能帮助我们写出更好更直观的面向对象的代码。
下面这是ES6中类与类的继承,实现的效果跟上面是一样的。
class Animal {
constructor(name){
this.name = name;
this.type = "动物";
} says(say){
console.info(this.type + "【" + this.name + "】" + "说 " + say);
}
} let dog = new Animal("狗狗");
dog.says("汪汪汪"); class Bird extends Animal {
constructor(name){
super(name);
this.type = "小鸟";
}
} let pigeon = new Bird("鸽子");
pigeon.says("我是一只小鸟");
实现是非常简单直观的,而且不会再被人称为这是“模拟继承”。
二、各有什么缺点
1、原型链继承利弊
1、只能单继承。2、继承后会影响所有的对象。3、速度略慢。
2、原型冒充继承利弊
1、虽然可以多继承,但是无法在运行的时候动态继承,只能修改父类的构造函数。
3、复制继承(非ES6推荐)
1、无。
因为上面两个所拥有的缺点它都很好地避开了,它可以实现多继承,继承只影响当前对象,而且速度快,不必修改父类的构造函数等等等等,所以最推荐的还是这种继承方式。
注:jQuery的继承也是采取复制继承实现的,不过jQuery加了很多的验证判断,但是原理是一样的。
4、ES6标准类的继承
如果能使用最新的ES6的特性,这种继承是最好的,通俗易懂,是标准的面向对象的语言该有的继承方式。
但是需要注意:
子类的contructor里,“this”必须放在super()调用之后
子类的contructor里必须调用super(),或者明确地返回一个对象
不能多继承
-- Java在继承的时候会自动生成一个父类对象,但是js里并不会
最新文章
- 如何使cookie全站都生效?
- 使用触发器实现记录oracle用户登录失败信息到alert.log日志文件
- 【CLR Via C#】第5章 基元类型、引用类型、值类型
- Eclipse_调试技巧
- DEDECMS中,友情链接
- OpenSSH Client信息泄露和缓冲区溢出漏洞
- SignalR2.0开发实例之——设置时间、后台其他地方使用集线器、使用自己的连接ID
- Unity3D之挥动武器产生的剑痕特效
- (Jquery)避免数据相加小数点后产生多位数和计算精度损失
- es5和es6实现lazyman
- 学生问的一道javascript面试题[来自腾讯]
- Java中常见的数据结构
- 33 ArcToolBox学习系列之数据管理工具箱——投影与变换(Projections and Transformations)未完待续……
- LeetCode第二题
- Gym 101606L - Lounge Lizards - [计算几何+LIS]
- HQL count(*)
- python3基础之文件对象操作
- css3整理--background-origin
- C#游戏开发中精确的时间调配
- R基础学习(三)-- 简单练习(shiny+mysql+barplot)