- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章JS继承实现方法及优缺点详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。那么如何在JS中实现继承呢?让我们拭目以待.
JS继承的实现方式 。
既然要实现继承,那么首先我们得有一个父类,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 定义一个动物类
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、原型链继承 。
核心: 将父类的实例作为子类的原型 。
1
2
3
4
5
6
7
8
9
10
11
12
|
function
Cat(){
}
Cat.prototype =
new
Animal();
Cat.prototype.name =
'cat'
;
// Test Code
var
cat =
new
Cat();
console.log(cat.name);
console.log(cat.eat(
'fish'
));
console.log(cat.sleep());
console.log(cat
instanceof
Animal);
//true
console.log(cat
instanceof
Cat);
//true
|
特点:
缺点:
要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中 。
无法实现多继承 。
来自原型对象的所有属性被所有实例共享(来自原型对象的引用属性是所有实例共享的)(详细请看附录代码: 示例1) 创建子类实例时,无法向父类构造函数传参 。
推荐指数:★★(3、4两大致命缺陷) 。
2017-8-17 10:21:43补充:感谢 MMHS 指出。缺点1中描述有误:可以在Cat构造函数中,为Cat实例增加实例属性。如果要新增原型属性和方法,则必须放在new Animal()这样的语句之后执行.
2018-9-10 00:03:45补充:感谢 IRVING_J 指出。缺点3中的描述不够充分。更正为:来自原型对象的所有属性被所有实例共享.
2、构造继承 。
核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型) 。
1
2
3
4
5
6
7
8
9
10
11
|
function
Cat(name){
Animal.call(
this
);
this
.name = name ||
'Tom'
;
}
// Test Code
var
cat =
new
Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat
instanceof
Animal);
// false
console.log(cat
instanceof
Cat);
// true
|
特点:
缺点:
推荐指数:★★(缺点3) 。
3、实例继承 。
核心:为父类实例添加新特性,作为子类实例返回 。
1
2
3
4
5
6
7
8
9
10
11
12
|
function
Cat(name){
var
instance =
new
Animal();
instance.name = name ||
'Tom'
;
return
instance;
}
// Test Code
var
cat =
new
Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat
instanceof
Animal);
// true
console.log(cat
instanceof
Cat);
// false
|
特点:
不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果 。
缺点:
推荐指数:★★ 。
4、拷贝继承 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
function
Cat(name){
var
animal =
new
Animal();
for
(
var
p
in
animal){
Cat.prototype[p] = animal[p];
}
Cat.prototype.name = name ||
'Tom'
;
}
// Test Code
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) 。
5、组合继承 。
核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
function
Cat(name){
Animal.call(
this
);
this
.name = name ||
'Tom'
;
}
Cat.prototype =
new
Animal();
// 感谢 @学无止境c 的提醒,组合继承也是需要修复构造函数指向的。
Cat.prototype.constructor = Cat;
// Test Code
var
cat =
new
Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat
instanceof
Animal);
// true
console.log(cat
instanceof
Cat);
// true
|
特点:
缺点:
调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了) 推荐指数:★★★★(仅仅多消耗了一点内存) 。
6、寄生组合继承 。
核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
function
Cat(name){
Animal.call(
this
);
this
.name = name ||
'Tom'
;
}
(
function
(){
// 创建一个没有实例方法的类
var
Super =
function
(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype =
new
Super();
})();
// Test Code
var
cat =
new
Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat
instanceof
Animal);
// true
console.log(cat
instanceof
Cat);
//true
感谢 @bluedrink 提醒,该实现没有修复constructor。
Cat.prototype.constructor = Cat;
// 需要修复下构造函数
|
感谢 @bluedrink 提醒,该实现没有修复constructor.
Cat.prototype.constructor = Cat; // 需要修复下构造函数 。
特点:
堪称完美 。
缺点:
实现较为复杂 。
推荐指数:★★★★(实现复杂,扣掉一颗星) 。
附录代码:
示例一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
function
Animal (name) {
// 属性
this
.name = name ||
'Animal'
;
// 实例方法
this
.sleep =
function
(){
console.log(
this
.name +
'正在睡觉!'
);
}
//实例引用属性
this
.features = [];
}
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属性值已经变化了.
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://www.cnblogs.com/jiangweichen88/p/10508871.html 。
最后此篇关于JS继承实现方法及优缺点详解的文章就讲到这里了,如果你想了解更多关于JS继承实现方法及优缺点详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
ODBC是一种连接数据库的开放标准。 ODBC(OpenDataBase Connectivity,开放数据库互连)是微软公司开放服务结构(WOSA,Windows OpenServices Ar
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
在我最近的 javascript 程序中(主要是为了好玩和概念验证)我有很多不同种类的对象,并且每种类型我都有相当数量的“实例”。所以我想我应该为这些使用类,但是由于它们非常简单,我可以直接构造它们而
我想知道图标(Material Design 图标)使用可绘制矢量形状(XML 文件)与图像资源(png 文件)的优缺点是什么? 最佳答案 正如我所见,这个问题是指光栅(例如 jpeg、png)和矢量
优点和缺点是什么使用 Plain Old Data (POD)structs\classes in C++ ? 在什么情况下应该更喜欢使用他们在非 POD 上? 具体来说,POD 在工作时有优势吗与序
我听说 Ctypes 会导致 Python 和 Windows 崩溃(或停止错误)。我应该远离他们的使用吗?我从哪里听到的?当我试图控制窗口的各个方面、自动化之类的东西时,它又回来了。 我听说过 sw
您能否解释一下在 iPhone 上存储数据的不同方式,以及每种方式的优缺点。 我已经阅读了很多关于 UserDefaults、CoreData、XML、plist 的内容……但我有点不知所措。 目前,
但对于关闭PING值后,网站能否被百度和GOOGLE等搜索引擎收录,很多人说法不一,有些说对收录没任何影响,也有人说影响不大,其实会不会影响,我也不是很清楚,我只能从我遇到情况的来分析一下。 7月
我正在寻找一个制作平台。我读过一些关于 gnu make 的文章,它在 Windows 平台上有一些问题(从斜杠/反斜杠到 shell 确定......)所以我想听听我有什么替代品? 如果重要的话,我
我是 Ubuntu Linux 用户,我仅将 Win XP 用于我的工作目的。 最近我用 XP + Visual Studio 2008(由 kvm-quemu 提供支持)设置了一个虚拟机。 我的问题
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 5 年前。 Improv
我对使用Grails Portlets plugin在Grails上开发 Liferay portlet的可能性感兴趣。我认为引入portlet框架(例如Spring Portlet API)将使开发
作为Photon的新手,有以下问题: 看起来 VMware 正在尝试创建与 Docker 并行的容器技术。由于现阶段docker比较成熟,使用photon有什么好处/优势吗? 我知道有人可以在内部使用
我只需要一些关于此布局的建议。我不是经验丰富的 CSS 用户,所以我遇到的唯一技术是将所有内容包装到一个 div 中,设置宽度和自动左/右边距。这种方法是面向 future 的吗? 在我开始之前我应该
我正在使用 jQuery Mobile 和 Phonegap 开发 HTML5 移动应用程序。它将部署在多个平台上。 我在下面有一个横幅 png: 我的问题是: 1)直接用这张图片做背景还是用CSS动
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
这个问题在这里已经有了答案: When is it necessary or convenient to use Spring or EJB3 or all of them together? (2
我最近听说了 JavaScript 对象表示法 (JSON),在查找之后,它似乎作为可扩展标记语言 (XML) 的替代品变得相当流行。 我继续 this页面以获取更多信息,但它似乎更像是一个 XML
这个问题在这里已经有了答案: 9年前关闭。 Possible Duplicate: EF 4.1 Code-first vs Model/Database-first 我刚刚开始学习 EF 4.0 C
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我是一名优秀的程序员,十分优秀!