基于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 给汉字排序实例代码
Jun 28 Javascript
JavaScript 组件之旅(三):用 Ant 构建组件
Oct 28 Javascript
jqGrid读取选择的多行的某个属性代码
May 18 Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
Feb 13 Javascript
jquery append 动态添加的元素事件on 不起作用的解决方案
Jul 30 Javascript
jquery专业的导航菜单特效代码分享
Aug 29 Javascript
基于BootStarp的Dailog
Apr 28 Javascript
Vue下路由History模式打包后页面空白的解决方法
Jun 29 Javascript
微信小程序动画(Animation)的实现及执行步骤
Oct 28 Javascript
针对Vue路由history模式下Nginx后台配置操作
Oct 22 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
Nov 04 Javascript
Nest.js 授权验证的方法示例
Feb 22 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引用效率问题分析
2012/03/23 PHP
php获取通过http协议post提交过来xml数据及解析xml
2012/12/16 PHP
PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
2016/03/21 PHP
PHP抓取及分析网页的方法详解
2016/04/26 PHP
mac下多个php版本快速切换的方法
2016/10/09 PHP
PHP PDOStatement::fetch讲解
2019/01/31 PHP
Yaf框架封装的MySQL数据库操作示例
2019/03/06 PHP
Iframe thickbox2.0使用的方法
2009/03/05 Javascript
jQuery学习笔记 操作jQuery对象 属性处理
2012/09/19 Javascript
Javascript跨域请求的4种解决方式
2013/03/17 Javascript
谈谈JavaScript中的函数与闭包
2013/04/14 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
2016/01/05 Javascript
javascript基本语法
2016/05/31 Javascript
JS实现的表格行上下移动操作示例
2016/08/03 Javascript
JavaScript中日期函数的相关操作知识
2016/08/03 Javascript
基于vuejs+webpack的日期选择插件
2020/05/21 Javascript
微信小程序中button组件的边框设置的实例详解
2017/09/27 Javascript
Vue.js表单标签中的单选按钮、复选按钮和下拉列表的取值问题
2017/11/22 Javascript
jquery animate动画持续运动的实例
2017/11/29 jQuery
JS实现简单的星期格式转换功能示例
2018/07/23 Javascript
JS module的导出和导入的实现代码
2019/02/25 Javascript
帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
2019/08/23 Javascript
[01:03:22]LGD vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
[01:03:36]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第二场 1月26日
2021/03/11 DOTA
利用numpy实现一、二维数组的拼接简单代码示例
2017/12/15 Python
Anaconda下安装mysql-python的包实例
2018/06/11 Python
python生成带有表格的图片实例
2019/02/03 Python
python用for循环求和的方法总结
2019/07/08 Python
Python下载网易云歌单歌曲的示例代码
2020/08/12 Python
利用python如何实现猫捉老鼠小游戏
2020/12/04 Python
解决tensorflow模型压缩的问题_踩坑无数,总算搞定
2021/03/02 Python
客户代表自我评价范例
2013/09/24 职场文书
个人授权委托书
2014/09/15 职场文书
安徽导游词
2015/02/12 职场文书
小学六年级毕业感言
2015/07/30 职场文书
MySQL 逻辑备份 into outfile
2022/05/15 MySQL