基于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 相关文章推荐
javascript 播放器 控制
Jan 22 Javascript
(function(){})()的用法与优点
Mar 11 Javascript
很酷的javascript loading效果代码
Jun 18 Javascript
DIV始终居中的js代码
Feb 17 Javascript
jQuery判断当前点击的是第几个li的代码
Sep 26 Javascript
JQuery鼠标移到小图显示大图效果的方法
Jun 10 Javascript
JavaScript中关于iframe滚动条的去除和保留
Nov 17 Javascript
JSP防止网页刷新重复提交数据的几种方法
Nov 19 Javascript
用原生js做单页应用
Jan 17 Javascript
vue2实现移动端上传、预览、压缩图片解决拍照旋转问题
Apr 13 Javascript
node.js + socket.io 实现点对点随机匹配聊天
Jun 30 Javascript
浅谈Angular6的服务和依赖注入
Jun 27 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
web站点获取用户IP的安全方法 HTTP_X_FORWARDED_FOR检验
2013/06/01 PHP
php过滤html中的其他网站链接的方法(域名白名单功能)
2014/04/24 PHP
浅谈php冒泡排序
2014/12/30 PHP
PHP中的使用curl发送请求(GET请求和POST请求)
2017/02/08 PHP
Laravel实现定时任务的示例代码
2017/08/10 PHP
php7 图形用户界面GUI 开发示例
2020/02/22 PHP
Js中获取frames中的元素示例代码
2013/07/30 Javascript
javascript break指定标签打破多层循环示例
2014/01/20 Javascript
js去除输入框中所有的空格和禁止输入空格的方法
2014/06/09 Javascript
jQuery表单域属性过滤器用法分析
2015/02/10 Javascript
jquery中checkbox使用方法简单实例演示
2015/11/24 Javascript
js编写贪吃蛇的小游戏
2020/08/24 Javascript
javascript的列表切换【实现代码】
2016/05/03 Javascript
Javascript中级语法快速入手
2016/07/30 Javascript
浅谈js的html元素的父节点,子节点
2016/08/06 Javascript
jQuery EasyUI 获取tabs的实例解析
2016/12/06 Javascript
Bootstrap基本插件学习笔记之按钮(21)
2016/12/08 Javascript
AngularJS开发教程之控制器之间的通信方法分析
2016/12/25 Javascript
jQuery+Datatables实现表格批量删除功能【推荐】
2018/10/24 jQuery
快速搭建Node.js(Express)用户注册、登录以及授权的方法
2019/05/09 Javascript
v-slot和slot、slot-scope之间相互替换实例
2020/09/04 Javascript
前端如何实现动画过渡效果
2021/02/05 Javascript
从零学python系列之浅谈pickle模块封装和拆封数据对象的方法
2014/05/23 Python
pycharm 使用心得(一)安装和首次使用
2014/06/05 Python
python二维列表一维列表的互相转换实例
2018/07/02 Python
详解pandas.DataFrame.plot() 画图函数
2020/06/14 Python
Kendra Scott官网:美国领先的时尚配饰品牌
2020/10/22 全球购物
一套软件测试笔试题
2014/07/25 面试题
科学发展观活动总结
2014/08/28 职场文书
师德师风建设整改措施思想汇报
2014/10/11 职场文书
高考升学宴答谢词
2015/01/20 职场文书
世界环境日活动总结
2015/02/11 职场文书
幼儿园中秋节活动总结
2015/03/23 职场文书
生产车间管理制度
2015/08/04 职场文书
详解thinkphp的Auth类认证
2021/05/28 PHP