基于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 相关文章推荐
Js获取事件对象代码
Aug 05 Javascript
基于JQuery的asp.net树实现代码
Nov 30 Javascript
jquery 自定义容器下雨效果可将下雨图标改为其他
Apr 23 Javascript
将数字转换成大写的人民币表达式的js函数
Sep 21 Javascript
javascript实现的简单的表单验证
Jul 10 Javascript
jquery validate和jquery form 插件组合实现验证表单后AJAX提交
Aug 26 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
Nov 29 Javascript
angular select 默认值设置方法
Jun 23 Javascript
在vue项目中优雅的使用SVG的方法实例详解
Dec 03 Javascript
ES6 Promise对象的应用实例分析
Jun 27 Javascript
Vue在chrome44偶现点击子元素事件无法冒泡的解决方法
Dec 15 Javascript
js判断两个数组相等的5种方法
May 06 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
常用表单验证类,有了这个,一般的验证就都齐了。
2006/12/06 PHP
PHP 5.0对象模型深度探索之类的静态成员
2008/03/27 PHP
Codeigniter中mkdir创建目录遇到权限问题和解决方法
2014/07/25 PHP
php函数实现判断是否移动端访问
2015/03/03 PHP
PHP自定义函数实现格式化秒的方法
2016/09/14 PHP
JavaScript中将一个值转换为字符串的方法分析[译]
2012/09/21 Javascript
cookie 最近浏览记录(中文escape转码)具体实现
2013/06/08 Javascript
JS定时刷新页面及跳转页面的方法
2013/07/04 Javascript
JavaScript中使用stopPropagation函数停止事件传播例子
2014/08/27 Javascript
无限树Jquery插件zTree的常用功能特性总结
2014/09/11 Javascript
在JavaScript中使用NaN值的方法
2015/06/05 Javascript
简单实现异步编程promise模式
2015/07/31 Javascript
jQuery中prepend()方法使用详解
2015/08/11 Javascript
JS实现支持Ajax验证的表单插件
2016/03/24 Javascript
浅析$(function) ready和onload 的区别
2016/09/03 Javascript
Nodejs 获取时间加手机标识的32位标识实现代码
2017/03/07 NodeJs
关于vue-router的那些事儿
2018/05/23 Javascript
解决Vue-cli npm run build生产环境打包,本地不能打开的问题
2018/09/20 Javascript
Vuex新手的理解与使用详解
2019/05/31 Javascript
[51:53]完美世界DOTA2联赛循环赛 LBZS vs DM BO2第二场 11.01
2020/11/02 DOTA
[40:27]完美世界DOTA2联赛PWL S3 PXG vs GXR 第一场 12.19
2020/12/24 DOTA
python中subprocess批量执行linux命令
2018/04/27 Python
实例讲解Python3中abs()函数
2019/02/19 Python
python实现加密的方式总结
2020/01/19 Python
Python中实现输入一个整数的案例
2020/05/03 Python
PyQt5 文本输入框自动补全QLineEdit的实现示例
2020/05/13 Python
Python基于pandas绘制散点图矩阵代码实例
2020/06/04 Python
使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
2020/07/23 Python
墨西哥运动服饰和鞋网上商店:Netshoes墨西哥
2016/07/28 全球购物
波兰在线体育用品商店:Hop-Sport.pl
2019/07/23 全球购物
研究生自我鉴定范文
2013/10/30 职场文书
2014年党小组工作总结
2014/12/20 职场文书
办公室个人总结
2015/02/28 职场文书
自主招生自荐信范文
2015/03/04 职场文书
导游词之无锡唐城
2019/12/12 职场文书
如何用Navicat操作MySQL
2021/05/12 MySQL