JavaScript中的function是万能的,除了用于的函数定义,也可以用于类的定义。JavaScript的继承,说起来也是有点怪,没有public,private等访问控制修饰,也没有implement或其他特定的符号来说明是实现继承。关于javascript类的继承可以参考一下以下这个例子。
01 |
<script type="text/javascript"> |
04 |
this.Gender = "female"; |
06 |
this.Words = "Silence"; |
08 |
this.shouting = function() { |
13 |
function Programmer() { |
16 |
Programmer.prototype = new Person; |
18 |
Programmer.prototype.typeCode = function() { |
19 |
alert("俺是敲代码的!IT民工,很不开心。子类的方法"); |
23 |
var a = new Programmer(); |
24 |
alert(a.Gender); // 调用父类的属性 |
25 |
a.shouting(); // 调用父类的方法 |
26 |
a.typeCode(); // 调用子类的方法 |
模拟JavaScript中类和继承
在面向对象的语言中,我们使用类来创建一个自定义对象。然而JavaScript中所有事物都是对象,那么用什么办法来创建自定义对象呢?
这就需要引入另外一个概念 - 原型(prototype),我们可以简单的把prototype看做是一个模版,新创建的自定义对象都是这个模版(prototype)的一个拷贝 (实际上不是拷贝而是链接,只不过这种链接是不可见,给人们的感觉好像是拷贝)。
让我们看一下通过prototype创建自定义对象的一个例子:
02 |
function Person(name, sex) { |
06 |
// 定义Person的原型,原型中的属性可以被自定义对象引用 |
这里我们把函数Person称为构造函数,也就是创建自定义对象的函数。可以看出,JavaScript通过构造函数和原型的方式模拟实现了类的功能。
创建自定义对象(实例化类)的代码:
1 |
var zhang = new Person("ZhangSan", "man"); |
2 |
console.log(zhang.getName()); // "ZhangSan" |
3 |
var chun = new Person("ChunHua", "woman"); |
4 |
console.log(chun.getName()); // "ChunHua" |
当代码var zhang = new Person("ZhangSan", "man")执行时,其实内部做了如下几件事情:
- 创建一个空白对象(new Object())。
- 拷贝Person.prototype中的属性(键值对)到这个空对象中(我们前面提到,内部实现时不是拷贝而是一个隐藏的链接)。
- 将这个对象通过this关键字传递到构造函数中并执行构造函数。
- 将这个对象赋值给变量zhang。
为了证明prototype模版并不是被拷贝到实例化的对象中,而是一种链接的方式,请看如下代码:
01 |
function Person(name, sex) { |
05 |
Person.prototype.age = 20; |
06 |
var zhang = new Person("ZhangSan", "man"); |
07 |
console.log(zhang.age); // 20 |
10 |
console.log(zhang.age); // 19 |
12 |
// 在删除实例属性age后,此属性值又从prototype中获取 |
13 |
console.log(zhang.age); // 20 |
这种在JavaScript内部实现的隐藏的prototype链接,是JavaScript赖以生存的温润土壤,也是模拟实现继承的基础。
如何在JavaScript中实现简单的继承?
下面的例子将创建一个雇员类Employee,它从Person继承了原型prototype中的所有属性。
01 |
function Employee(name, sex, employeeID) { |
04 |
this.employeeID = employeeID; |
06 |
// 将Employee的原型指向Person的一个实例 |
07 |
// 因为Person的实例可以调用Person原型中的方法, 所以Employee的实例也可以调用Person原型中的所有属性。 |
08 |
Employee.prototype = new Person(); |
09 |
Employee.prototype.getEmployeeID = function() { |
10 |
return this.employeeID; |
12 |
var zhang = new Employee("ZhangSan", "man", "1234"); |
13 |
console.log(zhang.getName()); // "ZhangSan |
上面关于继承的实现很粗糙,并且存在很多问题:
- 在创建Employee构造函数和原型(以后简称类)时,就对Person进行了实例化,这是不合适的。
- Employee的构造函数没法调用父类Person的构造函数,导致在Employee构造函数中对name和sex属性的重复赋值。
- Employee中的函数会覆盖Person中的同名函数,没有重载的机制(和上一条是一个类型的问题)。
- 创建JavaScript类的语法过于零散,不如C#/Java中的语法优雅。
- 实现中有constructor属性的指向错误。
- JavaScript对寄生组合式继承的理解
有关JavaScript的几种继承方式请移步JavaScript的几种继承方式 原型链的缺陷 SubType.prototype = new SuperType(); 这样做的话,SuperType构 ...
- web前端学习(二) javascript对象和原型继承
目录 1. JavaScrpt对象 2. 原型对象和继承 3. 对象的克隆 (1)javascript对象 在JS中,对象是属性的容器.对于单个对象来说,都由属性名和属性值构成:其中属性名需要是标识符 ...
- 【面试必备】javascript的原型和继承
原型.闭包.作用域等知识可以说是js中面试必考的东西,通过你理解的深度也就能衡量出你基本功是否扎实.今天来复习一下javascript的原型和继承,虽说是老生常谈的话题,但对于这些知识,自己亲手写一遍 ...
- Javascript的实例化与继承:请停止使用new关键字
本文同时也发表在我另一篇独立博客 <Javascript的实例化与继承:请停止使用new关键字>(管理员请注意!这两个都是我自己的原创博客!不要踢出首页!不是转载!已经误会三次了!) 标题 ...
- 理解JavaScript中的原型继承(2)
两年前在我学习JavaScript的时候我就写过两篇关于原型继承的博客: 理解JavaScript中原型继承 JavaScript中的原型继承 这两篇博客讲的都是原型的使用,其中一篇还有我学习时的错误 ...
- Javascript之对象的继承
继承是面向对象语言一个非常重要的部分.许多OOP语言都支持接口继承和实现继承两种方式.接口继承:继承方法签名:实现继承:继承实际的方法.在ECMAScript中函数是没有签名的,所以也就无法实现接口继 ...
- javascript中的原型继承
在Javascript面向对象编程中,原型继承不仅是一个重点也是一个不容易掌握的点.在本文中,我们将对Javascript中的原型继承进行一些探索. 基本形式 我们先来看下面一段代码: <cod ...
- JavaScript面向对象中的继承
1.1继承的基本概念 使用一个子类,继承另一个父类,那么子类可以自动拥有父类中的所有属性和方法,这个过程叫做继承. >>>继承的两方,发生在两个类之间. 实现继承的三种方式: 扩展O ...
- Javascript 进阶 面向对象编程 继承的一个样例
Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承.这篇使用一个样例来展示js怎样面向对象编程.以及怎样基于类实现继承. 1. ...
- Javascript 进阶 面向对象编程 继承的一个例子
Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承,这篇使用一个例子来展示js如何面向对象编程,以及如何基于类实现继承. 1. ...
随机推荐
- Unity编辑器 - 鼠标悬停在控件上时改变鼠标样式
Unity编辑器 - 鼠标悬停在控件上时改变鼠标样式 摘自Unity文档 EditorGUIUtility.AddCursorRect public static void AddCursorRect ...
- Laxcus大数据管理系统2.0(7)- 第五章 数据构建
第五章 数据构建 在数据处理过程,我们经常会遇到这样的情况:大多数时候,用户最初输入的数据会含有大量无意义的.杂乱的信息,需要经过提炼.收集.汇总等一系列手段,才能产生有意义和用户可识别的数据内容:当 ...
- Linux服务架设篇--arp命令
ARP,地址解析协议.在以太局域网中,主机之间交换数据帧时,是通过MAC地址进行的.因此,当以太网的一台主机向另一台IP地址的主机发送数据包时,它需要知道目的IP地址所对应的MAC地址,才能把这个IP ...
- Multi-task Correlation Particle Filter for Robust Object Tracking--论文随笔
摘要:在这篇论文中,作者提出一种鲁棒视觉跟踪的多任务相关粒子滤波琪跟踪算法(MCPF).作者首先向我们展示了多任务相关滤波器,该滤波器在训练滤波器模板的时候可以学习不同特征之间的联系.本文提出的MCP ...
- 六:YARN Node Labels
参考:http://dongxicheng.org/mapreduce-nextgen/hadoop-yarn-label-based-scheduling/ 为不同的DATANODE打标签,通过标签 ...
- 【转】c++面试基础
1,关于动态申请内存 答:内存分配方式三种: (1)从静态存储区域分配:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在. 全局变量,static变量. (2)在栈上创建:在执行函 ...
- 阿里云服务器 操作实战 部署C语言开发环境(vim配置,gcc) 部署J2EE网站(jdk,tomcat)
. 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/18964835 . 博客总结 : 设置SecureCRT ...
- 算法与数据结构实验题 6.3 search
★实验任务 可怜的 Bibi 刚刚回到家,就发现自己的手机丢了,现在他决定回头去搜索 自己的手机. 现在我们假设 Bibi 的家位于一棵二叉树的根部.在 Bibi 的心中,每个节点 都有一个权值 x, ...
- Qt代码覆盖率code coverage(VS版)
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt代码覆盖率code coverage(VS版) 本文地址:http://techi ...
- 【Linux】- rm命令
Linux rm命令用于删除一个文件或者目录. 语法 rm [options] name... 参数: -i 删除前逐一询问确认. -f 即使原档案属性设为唯读,亦直接删除,无需逐一确认. -r 将目 ...