深入理解JavaScript是如何实现继承的


Posted in Javascript onDecember 12, 2013

最近最网上看了一个人面试淘宝时的经历,然后发现了自己有好多好多不太清楚的地方,所以特此写点文章来加深自己对一些问题的理解。

文章中提到了一个问题是:JavaScript是如何实现继承的?

下面我便阐述一些在网上找到的方法和实例来解释下,借以加深自己的印象。

我们知道JavaScript中的function是万能的,除了用于的函数定义,也可以用于类的定义。

JavaScript的继承,说起来也是有点怪,不像C++和一些面向对象的语言,他没有public,private等访问控制修饰,也没有implement或其他特定的符号来说明是实现继承。

关于javascript类的继承可以参考一下下面的这个例子。

<script type="text/javascript"> 
function Person() {
    // 属性 
    this.Gender = "female";
    this.Age = 18;
    this.Words = "Silence";
    // 方法
    this.shouting = function() {
        alert("开心哦!父类的方法");
    }
}
// 继承
function Programmer() {
    this.base = Person;
}
Programmer.prototype = new Person;
// 为子类添加新的方法
Programmer.prototype.typeCode = function() {
    alert("俺是敲代码的!IT民工,很不开心。子类的方法");
}
// 调用示例
function sayHello() {
    var a = new Programmer();
    alert(a.Gender); // 调用父类的属性
    a.shouting(); // 调用父类的方法
    a.typeCode(); // 调用子类的方法
}        
sayHello();
</script>

上例中,首先是声明一个person类,里面包含了一些属性和方法,然后接着又声明了一个programmer类,其中有个base属性,这个属性并不是必需的,但是出于规范以及以后在查找对象所继承的类时都需要写上,然后是给programmer的原型对象(prototype)拷贝了person类;于是便实现了类的继承。

模拟JavaScript中类和继承的一些原理

在面向对象的语言中,我们使用类来创建一个自定义对象。然而JavaScript中所有事物都是对象,那么用什么办法来创建自定义对象呢?

这就需要引入另外一个概念 - 原型(prototype),我们可以简单的把prototype看做是一个模版,新创建的自定义对象都是这个模版(prototype)的一个拷贝 (实际上不是拷贝而是链接,只不过这种链接是不可见,给人们的感觉好像是拷贝)。

让我们看一下通过prototype创建自定义对象的一个例子:

// 构造函数
  function Person(name, sex) {
      this.name = name;
      this.sex = sex;
  }
  // 定义Person的原型,原型中的属性可以被自定义对象引用
  Person.prototype = {
      getName: function() {
          return this.name;
      },
      getSex: function() {
          return this.sex;
      }
  }

这里我们把函数Person称为构造函数,也就是创建自定义对象的函数。可以看出,JavaScript通过构造函数和原型的方式模拟实现了类的功能。

下面通过一个例子来具体阐述创建一个自定义对象,javascript所做的具体的工作:

var zhang = new Person("ZhangSan", "man");
console.log(zhang.getName()); // "ZhangSan"
var chun = new Person("ChunHua", "woman");
console.log(chun.getName()); // "ChunHua"

当代码var zhang = new Person("ZhangSan", "man")执行时,其实内部做了如下几件事情:

创建一个空白对象(new Object())。
拷贝Person.prototype中的属性(键值对)到这个空对象中(我们前面提到,内部实现时不是拷贝而是一个隐藏的链接)。
将这个对象通过this关键字传递到构造函数中并执行构造函数。
将这个对象赋值给变量zhang。
所有工作完成。
为了证明prototype模版并不是被拷贝到实例化的对象中,而是一种链接的方式,请看如下代码:

function Person(name, sex) {
    this.name = name;
    this.sex = sex;
}
Person.prototype.age = 20;
var zhang = new Person("ZhangSan", "man");
console.log(zhang.age); // 20
// 覆盖prototype中的age属性
zhang.age = 19;
console.log(zhang.age); // 19
delete zhang.age;
// 在删除实例属性age后,此属性值又从prototype中获取
console.log(zhang.age); // 20

在上面的这个例子中,如果他仅仅是通过拷贝得来的,则在删除了这个age这个属性后,这个对象里面将不会存在,但是例子中的age属性还能输出,还是覆盖以前的值,说明我们仅仅是删除了子类中同名的属性,而父类当中的age属性通过一种不可见的链接依然存在在对象中。

如何在JavaScript中实现简单的继承?

下面的例子将创建一个雇员类Employee,它从Person继承了原型prototype中的所有属性。

function Employee(name, sex, employeeID) {
    this.name = name;
    this.sex = sex;
    this.employeeID = employeeID;
}
// 将Employee的原型指向Person的一个实例
// 因为Person的实例可以调用Person原型中的方法, 所以Employee的实例也可以调用Person原型中的所有属性。
Employee.prototype = new Person();
Employee.prototype.getEmployeeID = function() {
    return this.employeeID;
};
var zhang = new Employee("ZhangSan", "man", "1234");
console.log(zhang.getName()); // "ZhangSan

好了,以上就是一些关于javascript实现继承的具体过程,和实现继承的方法。

当然总结一下,javascript中的继承机制仅仅是靠模拟的,于一些面向对象的语言来讲,显的粗糙而且还有一些缺陷,不过总的来讲,这依然不并会降低前端开发者在这方面的热情。

Javascript 相关文章推荐
JavaScript的面向对象方法以及差别
Mar 31 Javascript
Javascript操作URL函数修改版
Nov 07 Javascript
查找Oracle高消耗语句的方法
Mar 22 Javascript
javascript实现获取cookie过期时间的变通方法
Aug 14 Javascript
jQuery实现可展开折叠的导航效果示例
Sep 12 Javascript
js图片延迟加载(Lazyload)三种实现方式
Mar 01 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
Jul 17 Javascript
10个经典的网页鼠标特效代码
Jan 09 Javascript
jQuery实现简单复制json对象和json对象集合操作示例
Jul 09 jQuery
layui 中select下拉change事件失效的解决方法
Sep 20 Javascript
vue 动态生成拓扑图的示例
Jan 03 Vue.js
vue代码分块和懒加载非必要资源文件
Apr 11 Vue.js
Javascript Ajax异步读取RSS文档具体实现
Dec 12 #Javascript
javascripit实现密码强度检测代码分享
Dec 12 #Javascript
jQuery获取Radio,CheckBox选择的Value值(示例代码)
Dec 12 #Javascript
Jquery 改变radio/checkbox选中状态,获取选中的值(示例代码)
Dec 12 #Javascript
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
Dec 12 #Javascript
js中typeof的用法汇总
Dec 12 #Javascript
使用js判断数组中是否包含某一元素(类似于php中的in_array())
Dec 12 #Javascript
You might like
UCenter中的一个可逆加密函数authcode函数代码
2010/07/20 PHP
PHP常见错误提示含义解释(实用!值得收藏)
2016/04/25 PHP
thinkPHP多表查询及分页功能实现方法示例
2017/07/03 PHP
YII框架常用技巧总结
2019/04/27 PHP
使用laravel和ajax实现整个页面无刷新的操作方法
2019/10/03 PHP
jquery下操作HTML控件的实现代码
2010/01/12 Javascript
javascript textContent与innerText的异同分析
2010/10/22 Javascript
ExtJS中文乱码之GBK格式编码解决方案及代码
2013/01/20 Javascript
嵌入式iframe子页面与父页面js通信的方法
2015/01/20 Javascript
javascript内置对象操作详解
2015/02/04 Javascript
Bootstrap每天必学之导航
2015/11/26 Javascript
jQuery实现控制文字内容溢出用省略号(…)表示的方法
2016/02/26 Javascript
Bootstrap3学习笔记(三)之表格
2016/05/20 Javascript
Javascript iframe交互并兼容各种浏览器的解决方法
2016/07/12 Javascript
基于BootStrap的Metronic框架实现页面链接收藏夹功能按钮移动收藏记录(使用Sortable进行拖动排序)
2016/08/29 Javascript
bootstrap多层模态框滚动条消失的问题
2017/07/21 Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
2017/12/20 Javascript
深入理解JavaScript和TypeScript中的class
2018/04/22 Javascript
jQuery对底部导航进行跳转并高亮显示的实例代码
2019/04/23 jQuery
vue中监听返回键问题
2019/08/28 Javascript
vue+ElementUI 关闭对话框清空验证,清除form表单的操作
2020/08/06 Javascript
js实现盒子移动动画效果
2020/08/09 Javascript
JS实现简易图片自动轮播
2020/10/16 Javascript
[01:22]DOTA2神秘商店携大量周边降临完美大师赛
2017/11/07 DOTA
Windows下用py2exe将Python程序打包成exe程序的教程
2015/04/08 Python
python正则实现提取电话功能
2018/02/24 Python
django加载本地html的方法
2018/05/27 Python
Python爬虫动态ip代理防止被封的方法
2019/07/07 Python
Python Request爬取seo.chinaz.com百度权重网站的查询结果过程解析
2019/08/13 Python
使用python将最新的测试报告以附件的形式发到指定邮箱
2019/09/20 Python
python单例设计模式实现解析
2020/01/07 Python
关于win10在tensorflow的安装及在pycharm中运行步骤详解
2020/03/16 Python
印尼在线购买隐形眼镜网站:Lensza.co.id
2019/04/27 全球购物
心得体会该怎么写呢?
2019/06/27 职场文书
餐厅营销的秘密:为什么老顾客会流水?
2019/08/08 职场文书
Python+SeaTable实现计算两个日期间的工作日天数
2022/07/07 Python