基于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中匿名函数的N种写法
Sep 08 Javascript
jQuery学习总结之元素的相对定位和选择器(持续更新)
Apr 26 Javascript
原生javascript实现获取指定元素下所有后代元素的方法
Oct 28 Javascript
jQuery实现图片预加载效果
Nov 27 Javascript
jquery中键盘事件小结
Feb 24 Javascript
jQuery实现TAB选项卡切换特效简单演示
Mar 04 Javascript
jquery+css3问卷答题卡翻页动画效果示例
Oct 26 Javascript
剖析Angular Component的源码示例
Mar 23 Javascript
在Vue中用canvas实现二维码和图片合成海报的方法
Jun 10 Javascript
JavaScript Dom 绑定事件操作实例详解
Oct 02 Javascript
vue新建项目并配置标准路由过程解析
Dec 09 Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
May 03 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类分享
2014/02/07 PHP
php输出1000以内质数(素数)示例
2014/02/16 PHP
php查询ip所在地的方法
2014/12/05 PHP
Thinkphp实现站点静态化的方法详解
2017/03/21 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
找到了一篇jQuery与Prototype并存的冲突的解决方法
2007/08/29 Javascript
Javascript图像处理—亮度对比度应用案例
2013/01/03 Javascript
HTML5实现留言和回复页面样式
2015/07/22 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
2016/02/23 Javascript
再谈javascript注入 黑客必备!
2016/09/14 Javascript
JS实现重新加载当前页面或者父页面的几种方法
2016/11/30 Javascript
jQuery动态生成不规则表格(前后端)
2017/02/21 Javascript
Node.js数据库操作之连接MySQL数据库(一)
2017/03/04 Javascript
深入理解Vue 单向数据流的原理
2017/11/09 Javascript
vuex 使用文档小结篇
2018/01/11 Javascript
vue2.0 自定义组件的方法(vue组件的封装)
2018/06/05 Javascript
vue中如何去掉空格的方法实现
2018/11/09 Javascript
微信小程序导航栏滑动定位功能示例(实现CSS3的positionsticky效果)
2019/01/24 Javascript
微信小程序API—获取定位的详解
2019/04/30 Javascript
vue项目部署到nginx/tomcat服务器的实现
2019/08/26 Javascript
vue项目中使用bpmn为节点添加颜色的方法
2020/04/30 Javascript
CentOS7.3编译安装Python3.6.2的方法
2018/01/22 Python
Pandas 按索引合并数据集的方法
2018/11/15 Python
python中用logging实现日志滚动和过期日志删除功能
2019/08/20 Python
Python使用进程Process模块管理资源
2020/03/05 Python
Python手动或自动协程操作方法解析
2020/06/22 Python
plt.figure()参数使用详解及运行演示
2021/01/08 Python
计算机应用与科学个人的自我评价
2013/11/15 职场文书
快递业务员岗位职责
2014/01/06 职场文书
医学生求职信
2014/07/01 职场文书
运动会通讯稿100字
2015/07/20 职场文书
药品销售员2015年终工作总结
2015/10/22 职场文书
ORACLE数据库对long类型字段进行模糊匹配的解决思路
2021/04/07 Oracle
ConstraintValidator类如何实现自定义注解校验前端传参
2021/06/18 Java/Android
navicat 连接Ubuntu虚拟机的mysql的操作方法
2022/04/02 MySQL
js 实现Material UI点击涟漪效果示例
2022/09/23 Javascript