基于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 相关文章推荐
jquery判断单个复选框是否被选中的代码
Sep 03 Javascript
在IE下获取object(ActiveX)的Param的代码
Sep 15 Javascript
js中onload与onunload的使用示例
Aug 25 Javascript
$.get获取一个文件的内容示例代码
Sep 11 Javascript
下拉列表select 由左边框移动到右边示例
Dec 04 Javascript
jquerymobile局部渲染的各种刷新方法小结
Mar 05 Javascript
使用jquery.upload.js实现异步上传示例代码
Jul 29 Javascript
ECMAScript 5严格模式(Strict Mode)介绍
Mar 02 Javascript
JavaScript运动框架 多值运动(四)
May 18 Javascript
vue-cli+webpack在生成的项目中使用bootstrap实例代码
May 26 Javascript
Angular-UI Bootstrap组件实现警报功能
Jul 16 Javascript
中级前端工程师必须要掌握的27个JavaScript 技巧(干货总结)
Sep 23 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
PHP实现分页的一个示例
2006/10/09 PHP
PHP教程 预定义变量
2009/10/23 PHP
PHP远程调试之XDEBUG
2015/12/29 PHP
JavaScript对象、属性、事件手册集合方便查询
2010/07/04 Javascript
Javascript基础 函数“重载” 详细介绍
2013/10/25 Javascript
Java/JS获取flash高宽的具体方法
2013/12/27 Javascript
jquery获得keycode的示例代码
2013/12/30 Javascript
在页面上用action传递参数到后台出现乱码的解决方法
2013/12/31 Javascript
红米手机抢购的js代码
2014/03/10 Javascript
jQuery循环动画与获取组件尺寸的方法
2015/02/02 Javascript
jQuery插件kinMaxShow扩展效果用法实例
2015/05/04 Javascript
javascript实现日期按月份加减
2015/05/15 Javascript
解决jquery实现的radio重新选中的问题
2015/07/03 Javascript
关于JavaScript限制字数的输入框的那些事
2016/08/14 Javascript
使用 Opentype.js 生成字体子集的实例代码详解
2020/05/25 Javascript
在HTML中使用JavaScript的两种方法
2020/12/24 Javascript
[40:17]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第一场
2018/04/06 DOTA
Python中使用logging模块打印log日志详解
2015/04/05 Python
Python实现读取json文件到excel表
2017/11/18 Python
修改python plot折线图的坐标轴刻度方法
2018/12/13 Python
对python中xlsx,csv以及json文件的相互转化方法详解
2018/12/25 Python
详细分析Python collections工具库
2020/07/16 Python
python 基于wx实现音乐播放
2020/11/24 Python
python给list排序的简单方法
2020/12/10 Python
ProBikeKit英国:在线公路自行车之家
2017/02/10 全球购物
不开辟用于交换数据的临时空间,如何完成字符串的逆序
2012/12/02 面试题
大三学生入党思想汇报
2014/01/02 职场文书
商场中秋节广播稿
2014/01/17 职场文书
体育教师个人的自我评价
2014/02/16 职场文书
人力资源经理的岗位职责
2014/03/02 职场文书
跳蚤市场口号
2014/06/13 职场文书
私人房屋买卖协议书
2014/10/04 职场文书
周一给客户的问候语
2015/11/10 职场文书
生活委员竞选稿
2015/11/21 职场文书
python自动化测试通过日志3分钟定位bug
2021/11/20 Python
Mysql 8.x 创建用户以及授予权限的操作记录
2022/04/18 MySQL