基于JavaScript实现继承机制之原型链(prototype chaining)的详解


Posted in Javascript onMay 07, 2013

如果用原型方式重定义前面例子中的类,它们将变为下列形式:

function ClassA() {
}
ClassA.prototype.color = "blue";
ClassA.prototype.sayColor = function () {
    alert(this.color);
};
function ClassB() {
}
ClassB.prototype = new ClassA();

原型方式的神奇之处在于最后一行代码。这里,把 ClassB 的 prototype 属性设置成 ClassA 的实例。这很有意思,因为想要 ClassA 的所有属性和方法,但又不想逐个将它们 添加到ClassB 的 prototype 属性。还有比把 ClassA 的实例赋予 prototype 属性更好的方法吗?

注意:调用 ClassA 的构造函数,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。

与对象冒充相似,子类的所有属性和方法都必须出现在 prototype 属性被赋值后,因为在它之前赋值的所有方法都会被删除。为什么?因为 prototype 属性被替换成了新对象,添加了新方法的原始对象将被销毁。所以,为 ClassB 类添加 name 属性和 sayName() 方法的代码如下:

function ClassB() {
}
ClassB.prototype = new ClassA();
ClassB.prototype.name = "";
ClassB.prototype.sayName = function () {
    alert(this.name);
};

可通过运行下面的例子测试这段代码:
var objA = new ClassA();
var objB = new ClassB();
objA.color = "blue";
objB.color = "red";
objB.name = "John";
objA.sayColor();
objB.sayColor();
objB.sayName();

此外,在原型链中,instanceof 运算符的运行方式也很独特。对 ClassB 的所有实例,instanceof 为 ClassA 和 ClassB 都返回 true。例如:
var objB = new ClassB();
alert(objB instanceof ClassA);    //输出 "true"
alert(objB instanceof ClassB);    //输出 "true"

在 ECMAScript 的弱类型世界中,这是极其有用的工具,不过使用对象冒充时不能使用该方法判断。但是由于子类的原型被直接重新赋值,所以出现以下这种情况:
console.log(objB.__proto__===objB.constructor.prototype)   //false

因为ClassB的原型链 prototype 属性被另一个类的对象重写了。输出结果可以看出objB.__proto__仍然指向的是ClassB.prototype,而不是objB.constructor.prototype。这也很好理解,给Person.prototype赋值的是一个对象直接量new ClassA()实例,使用对象直接量方式定义的对象其构造器(constructor)指向的是根构造器Object,Object.prototype是一个空对象{},{}自然与ClassB.prototype不等。
Javascript 相关文章推荐
跨浏览器通用、可重用的选项卡tab切换js代码
Sep 20 Javascript
javascript根据像素点取位置示例
Jan 27 Javascript
AngularJS基础知识笔记之表格
May 10 Javascript
Hammer.js+轮播原理实现简洁的滑屏功能
Feb 02 Javascript
给angular加上动画效遇到的问题总结
Feb 17 Javascript
javascript实现九宫格相加数值相等
May 28 Javascript
基于 Node.js 实现前后端分离
Apr 23 Javascript
JavaScript中的冒泡排序法
Aug 03 Javascript
Layui给数据表格动态添加一行并跳转到添加行所在页的方法
Aug 20 Javascript
JS实现点击按钮随机生成可拖动的不同颜色块示例
Jan 30 Javascript
JavaScript实现滑动门效果
Jan 18 Javascript
JavaScript实现动态生成表格
Aug 02 Javascript
基于JavaScript实现继承机制之构造函数+原型链混合方式的使用详解
May 07 #Javascript
使用javascript:将其它类型值转换成布尔类型值的解决方法详解
May 07 #Javascript
JQuery+CSS提示框实现思路及代码(纯手工打造)
May 07 #Javascript
基于IE下ul li 互相嵌套时的bug,排查,解决过程以及心得介绍
May 07 #Javascript
解决javascript:window.close()在chrome,Firefox下失效的问题
May 07 #Javascript
jQuery的slideToggle方法实例
May 07 #Javascript
jQuery实现动画效果的实例代码
May 07 #Javascript
You might like
无线电的诞生过程
2021/03/01 无线电
PHP删除特定数组内容并且重建数组索引的方法.
2011/03/25 PHP
php 生成唯一id的几种解决方法
2013/03/08 PHP
浅谈web上存漏洞及原理分析、防范方法(安全文件上存方法)
2013/06/29 PHP
php构造函数实例讲解
2013/11/13 PHP
Yii2 rbac权限控制操作步骤实例教程
2016/04/29 PHP
关于laravel-admin ueditor 集成并解决刷新的问题
2019/10/21 PHP
js 判断checkbox是否选中的操作方法
2012/11/09 Javascript
fckeditor粘贴Word时弹出窗口取消的方法
2014/10/30 Javascript
javascript实现C语言经典程序题
2015/11/29 Javascript
关于JavaScript限制字数的输入框的那些事
2016/08/14 Javascript
让编辑器支持word复制黏贴、截屏的js代码
2016/10/17 Javascript
js 实现一些跨浏览器的事件方法详解及实例
2016/10/27 Javascript
微信小程序 this和that详解及简单实例
2017/02/13 Javascript
jQuery插件HighCharts实现的2D回归直线散点效果示例【附demo源码下载】
2017/03/09 Javascript
jq checkbox 的全选并ajax传参的实例
2017/04/01 Javascript
基于Bootstrap table组件实现多层表头的实例代码
2017/09/07 Javascript
React Native中的RefreshContorl下拉刷新使用
2017/10/09 Javascript
实例分析JS与Node.js中的事件循环
2017/12/12 Javascript
Express下采用bcryptjs进行密码加密的方法
2018/02/07 Javascript
在vue中封装的弹窗组件使用队列模式实现方法
2020/07/23 Javascript
jquery实现广告上下滚动效果
2021/03/04 jQuery
[03:46]DOTA2英雄基础教程 维萨吉
2013/12/11 DOTA
pandas.DataFrame.to_json按行转json的方法
2018/06/05 Python
解决python调用自己文件函数/执行函数找不到包问题
2020/06/01 Python
Python基于os.environ从windows获取环境变量
2020/06/09 Python
计算机科学与技术应届生求职信
2013/11/07 职场文书
三年级评语大全
2014/04/23 职场文书
项目经理任命书
2014/06/04 职场文书
运动会演讲稿200字
2014/08/25 职场文书
房屋买卖协议书范本
2014/09/27 职场文书
教师党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
离婚协议书样本
2015/01/26 职场文书
大学生入党自荐书
2015/03/05 职场文书
幼儿园托班开学寄语(2015秋季)
2015/05/27 职场文书
解决jupyter notebook启动后没有token的坑
2021/04/24 Python