当前位置: 首页 > 编程日记 > 正文

JS实现继承的几种方法

父类:

// 定义一个动物的类
function Animal (name) {// 属性this.name = name || 'Animal';// 实例方法this.sleep = function(){console.log(this.name + ' 正在睡午觉!');}
}
// 原型方法
Animal.prototype.eat = function(food) {console.log(this.name + '正在吃:' + food);
};

1、原型链继承

核心:将父类的实例作为子类的原形

function Cat() {}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';var cat = new Cat();
console.log(cat.name);  // cat
console.log(cat.eat('fish');
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true 

特点:

1.非常纯粹的继承关系,实例是子类的实例,也是父类的实例

2.父类新增原形方法/原形属性,子类都能访问到

3.简单,易于实现

缺点:

1.要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中;

2.无法实现多继承;

3.来自原型对旬的引用属性是所有实例共享的(附录示例1);

4.创建子类实例时,无法向父类构造函数传参

2、构造继承

核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)

function Dog(name) {Animal.call(this);this.name = name || 'Tom';
}var dog = new Dog();
console.log(dog.name);
console.log(dog.sleep());
console.log(dog instanceof Animal); // false
console.log(dog instanceof Dog); true

特点:

1.解决了1中,子类实例共享父类引用属性的问题

2.创建子类实例时,可以向父类传递参数

3.可以实现多继承(call多个父类对象)

缺点:

1.实例并不是父类的实例,只是子类的实例

2.只能继承父类的实例属性和方法,不能继承原型属性/方法

3.无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

3、实例继承

核心:为父类实例添加新特性,作为子类实例返回

function Cat (name) {var instance = new Animal();instance.name = name || 'Tom';return instance;
}// 测试代码
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false

特点:

1.不限制调用方式,不管是new子类() 还是子类(),返回的对象具有相同的效果

缺点:

1.实例是父类的实例,不是子类的实例

2.不支持多继承

4、拷贝继承

function Cat (name) {var animal = new Animal();for (var p in animal) {Cat.prototype[p] = animal[p];}Cat.prototype.name = name || 'Tom';
}// 测试代码
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true

特点:

1.支持多继承

缺点:

1.效率较低,内存占用高(因为要拷贝父类的属性)

2.无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)

PS:推荐指数:★(缺点1)

5、组合继承

核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

function Cat (name) {Animal.call(this);this.name = name || 'Tom';
}
Cat.prototype = new Animal();// 测试代码
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true

特点:

1.弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法

2.既是子类的实例,也是父类的实例

3.不存在引用属性共享的问题

4.可传参

5.函数可复用

缺点:

1.调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

推荐指数:★★★★(仅仅多消耗了一点内存)

6、寄生组合继承

核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点

function Cat (name) {Animal.call(this);this.name = name || 'Tom';
}
(function(){// 创建一个没有实例方法的类var Super = function(){};Super.prototype = Animal.prototype;// 将实例作为子类的原型Cat.prototype = new Super();
})()// 测试代码
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true

特点:

1.堪称完美

缺点:

1.实现较为复杂

推荐指数:★★★★(实现复杂,扣掉一颗星)

附录代码:

示例一:

function Animal (name) {// 属性this.name = name || 'Animal';// 实例方法this.sleep = function(){console.log(this.name + '正在睡觉');}// 实例引用属性this.featrues = [];
}function Cat (name) {
}
Cat.prototype = new Animal();var tom = new Cat('Tom');
var kissy = new Cat('Kissy');console.log(tom.name); // "Animal"
console.log(kissy.name); // "Animal"
console.log(tom.features); // []
console.log(kissy.features); // []

tom.name = 'Tom-New Name';
tom.features.push('eat');//针对父类实例值类型成员的更改,不影响
console.log(tom.name); // 'Tom-New Name'
console.log(kissy.name); // 'Animal'
//针对父类实例引用类型成员的更改,会通过影响其他子类实例
console.log(tom.features); // ['eat']
console.log(kissy.features); // ['eat']

原因分析:

关键点:属性查找过程

执行tom.features.push,首先找tom对象的实例属性(找不到),

那么就去原形对象中找,也就是Animal的实例。发现有,那么就直接在这个对象 的features属性中插入值。

在console.log(kissy.features); 的时候。同上,kissy实例上没有,那么就去原型上找。刚好原型上有,就直接返回,但是注意,这个原型对象中features属性值已经变化了。

转载:http://www.cnblogs.com/humin/p/4556820.html

转载于:https://www.cnblogs.com/garfieldzhong/p/7255439.html

相关文章:

【怎样写代码】复杂对象的组装与创建 -- 建造者模式(四):扩展案例

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。 If you like the content here, you can give me the greatest help is forwarding, tell your friends, encourage them to learn together.

接口测试和单元测试的区别

1、单元测试注重代码逻辑,接口测试注重业务逻辑; 2、单元测试的粒度最小,是测试最小独立的单元模块(不依赖其他模块);接口测试不是,会覆盖很多; 3、单元测试是白盒测试&#xff0c…

改善FLEX/FLASH性能的小技巧(转)

使用下面的几个改善性能的技巧,如果你使用Flex Builder,那么可以使用调试窗口查看你的程序中关键的几步创建对象和内存回收的情况。有时细小的调整会造成很大的不同。下面是一小部分能够改善你的程序性能的做法:1)如果不知道一个对象的类型&a…

机器学习算法(3:决策树算法)

一、决策树简介 决策树是附加概率结果的一个树状的决策图,是直观的运用统计概率分析的图法。机器学习中决策树是一个预测模型,它表示对象属性和对象值之间的一种映射,一颗决策树是一棵有向无环树,它由若干个节点、分支、分裂谓词以…

【怎样写代码】复杂对象的组装与创建 -- 建造者模式(三):建造者模式

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。 If you like the content here, you can give me the greatest help is forwarding, tell your friends, encourage them to learn together.

Junit单元测试需要知道的一些知识点

Junit单元测试框架—基于java语言对的主流单元测试框架 beforeClass—位于数据准备前期或者其他前期准备(测试类调用前) --用于提取代码中的共用部分减少冗余,只能声明注解一次 --必须在public static void,方法名随意,&#x…

关闭Windows 2000/XP/2003默认共享

Windows 2000/XP/2003版本的操作系统提供了默认共享功能,这些默认的共享都有“$”标志,意为隐含的,包括所有的逻辑盘(C$,D$,E$……)和系统目录Winnt或Windows(admin$)。 …

MySQL 代码结构与基本流程

一、MySQL基本架构二、MySQL目录结构build: 内含有各个平台、各种编译器下进行编译的脚本。如compile-pentium-debug表示在pentium架构上进行调试编译的脚本。client: 客户端工具,如mysql,mysqladmin之类。cmd-line-utils: readline,libedit工具。config: 给aclocal…

【怎样写代码】复杂对象的组装与创建 -- 建造者模式(五):关于Director的进一步讨论

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。 If you like the content here, you can give me the greatest help is forwarding, tell your friends, encourage them to learn together.

如何进行app的兼容性测试?需要考虑哪些方面?

考虑的方面: 1. 系统 a. Android 1). 官方版:官方发型的版本 数据来源:https://mta.qq.com/mta/data/device/os 2). 定制版:华为、魅族、小米、三星。 (前三:华为、oppo、vivo) 数据来源:https://mta.qq.com/mta…

.NET Framework 4.0的新特性

本文将揭示.NET 4.0中的3个新特性:图表控件、SEO支持以及ASP.NET 4可扩展的输出缓存。 图表控件 微软向开发者提供了大量可免费下载的图表控件,可以在.NET 3.5 ASP.NET或WinForms项目中使用这些控件。要想在Visual Studio 2008中使用这些控件则需要安装一…

【怎样写代码】确保对象的唯一性 -- 单例模式(一):问题案例

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。 If you like the content here, you can give me the greatest help is forwarding, tell your friends, encourage them to learn together.

《Kinect应用开发实战:用最自然的方式与机器对话》一3.4 深度图像成像原理...

3.4 深度图像成像原理 Kinect有发射、捕捉、计算视觉重现的类似过程。严格说来,Kinect的“深度眼睛”是由一个红外投影机和红外摄像头组合而成的,投影和接收互为重叠,如图3-27所示。 可以说,Kinect的成功也在于其能廉价而有效地捕…

UI设计不够高端?这5个小技巧可以试试

UI培训设计是对软件的人机交互、操作逻辑、界面美观度的整体设计。好的UI设计不仅要让软件变得漂亮舒适,还要充分考虑到用户的操作问题。 从事UI设计的朋友们,肯定知道我们在做UI设计时,其实是可以通过一些小技巧来帮我们设计的界面更加的漂…

Apache学习路线

参考资料: 1、《Apache源代码全景分析》 2、《鸟哥服务器架设篇》 一、不同的开发人员应该关注的知识点 Apache管理员 配置文件、配置指令 模块开发人员 全部内容 服务器开发人员 MPM并发处理框架 普通人员 …

大火的Apache Spark也有诸多不完美

现在如果你想要选择一个解决方案来处理企业中的大数据并不是难事,毕竟有很多数据处理框架可以任君选择,如Apache Samza,Apache Storm 、Apache Spark等等。Apache Spark应该是2016年风头最劲的数据处理框架,它在数据的批处理和实时…

【怎样写代码】确保对象的唯一性 -- 单例模式(二):解决方案

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。 If you like the content here, you can give me the greatest help is forwarding, tell your friends, encourage them to learn together.

零基础如何学习java技术?

想要学习java技术,担心自己是零基础学不会?最近有很多同学会问到这样的问题,千锋教育小编告诉你,零基础是可以学习java技术的,但是要去正规的java培训机构学习,下面来看看详细的介绍。 零基础如何学习java技术?我们…

Rank() over()的用法

Rank() over()的用法 创建一个test表,并插入6条数据。CREATE TABLE test (a INT,b INT,c CHAR ) INSERT INTO test VALUES(1,3,E) INSERT INTO test VALUES(2,4,A) INSERT INTO test VALUES(3,2,D) INSERT INTO test VALUES(3,5,B) INSERT INTO test VALUES(4,2,C) …

5G将成开启物联网时代的金钥匙

物联网其实并非新鲜事物,在互联网兴起之初,就有人提出了万物皆可通过网络互联,这被认为是物联网最早的定义。其实早在1995年比尔盖茨在其书《未来之路》也提到了物联网,当初并未引起重视。如今,随着互联网与先进通信技…

【怎样写代码】确保对象的唯一性 -- 单例模式(三):单例模式

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。 If you like the content here, you can give me the greatest help is forwarding, tell your friends, encourage them to learn together.

学习Python有什么优势?

学习Python的人越来越多,很多人就想知道,编程语言有那么多种,学习Python有什么优势?为什么这么多人会选择学习Python技术?今天我们就来聊一聊Python语言。 学习Python有什么优势? 入手快。Python语言相对于其他编程语言来说&am…

取消水晶报表的数据库登录框 分享

这两天在和斌做后台中的报表,暂定使用水晶报表,目前还只是处于对水晶报表的初级应用阶段,也就是知道如何 汇个总、写个函数、传个参数。 问题总是层出不穷,在最后整合报表,进行报表显示测试的时候,发现每次…

有光照就能上网 0.2秒即可下载一部高清电影

再也不用费尽心思询问 WIFI 密码了,以后,哪里有光照,哪里就可以上网。中国“可见光通信系统关键技术研究”近日取得重大突破,实时通信速率提升至 50Gbps,也就是说: 0.2 秒即可完成一部高清电影的下载。 有光…

【怎样写代码】确保对象的唯一性 -- 单例模式(四):饿汉式单例类与懒汉式单例类的讨论

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。 If you like the content here, you can give me the greatest help is forwarding, tell your friends, encourage them to learn together.

学Java需要学哪些书?

java技术所要学到的东西是很多的,只要入了这一行,学习是不能停止的,工作节奏在加快,新知识也源源不断,学习的最好途径就是看书,小编给大家推荐这几本java方面的书,搭配学习课程,让学…

【怎样写代码】确保对象的唯一性 -- 单例模式(五):一种更好的单例实现方法(静态内部类)

如果喜欢这里的内容,你能够给我最大的帮助就是转发,告诉你的朋友,鼓励他们一起来学习。 If you like the content here, you can give me the greatest help is forwarding, tell your friends, encourage them to learn together.

郭为:大数据时代的企业管理挑战

互联网时代,创新使得财富积累的速度前所未有的快,贫富不均也前所未有地分化。这个时代,世界的竞争变成人与人的竞争,人与人的竞争就是智慧的竞争,就是人的创新能力的竞争。如何才能提高人的竞争力,是管理科…

如何挑选靠谱的Java培训机构

想要学习java技术的人越来越多,市面上出现的java培训机构也越来越多,很多人都想找一个靠谱的java培训机构,那么到底该如何挑选靠谱的Java培训机构呢?看看下面小编为大家做的详细介绍吧。 如何挑选靠谱的Java培训机构? 首先挑选java培训机…

ActiveMQ在C#中的应用

ActiveMQ是个好东东,不必多说。ActiveMQ提供多种语言支持,如Java, C, C, C#, Ruby, Perl, Python, PHP等。由于我在windows下开发GUI,比较关心C和C#,其中C#的ActiveMQ很简单,Apache提供NMS(.Net Messaging …