基于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的一些看法
May 27 Javascript
Jquery AutoComplete自动完成 的使用方法实例
Mar 19 Javascript
Javascript 去除数组的重复元素
May 04 Javascript
jquery.boxy插件的iframe扩展代码
Jul 02 Javascript
Javascript(AJAX)解析XML的代码(兼容FIREFOX/IE)
Jul 11 Javascript
关于JavaScript中var声明变量作用域的推断
Dec 16 Javascript
js实现addClass,removeClass,hasClass的函数代码
Jul 13 Javascript
JavaScript cookie的设置获取删除详解
Feb 11 Javascript
jquery表单验证实例仿Toast提示效果
Mar 03 Javascript
使用JavaScript开发跨平台的桌面应用详解
Jul 27 Javascript
解决vue项目使用font-awesome,build后路径的问题
Sep 01 Javascript
如何区分vue中的v-show 与 v-if
Sep 08 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
vBulletin HACK----关于排版的两个HACK
2006/10/09 PHP
php页面缓存ob系列函数介绍
2012/10/18 PHP
php模板原理讲解
2013/11/13 PHP
是 WordPress 让 PHP 更流行了 而不是框架
2016/02/03 PHP
ThinkPHP模板Volist标签嵌套循环输出多维数组的方法
2016/03/23 PHP
自制PHP框架之设计模式
2017/05/07 PHP
基于PHP+mysql实现新闻发布系统的开发
2020/08/06 PHP
JavaScript 面向对象之命名空间
2010/05/04 Javascript
离开页面时检测表单元素是否被修改,提示保存的js代码
2010/08/25 Javascript
ui组件之input多选下拉实现方法(带有搜索功能)
2016/07/14 Javascript
详解如何较好的使用js
2016/12/16 Javascript
js模拟微博发布消息
2017/02/23 Javascript
简单实现js菜单栏切换效果
2017/03/04 Javascript
javascript实现圣旨卷轴展开效果(代码分享)
2017/03/23 Javascript
vue动态路由实现多级嵌套面包屑的思路与方法
2017/08/16 Javascript
详解使用React全家桶搭建一个后台管理系统
2017/11/04 Javascript
基于vue.js无缝滚动效果
2018/01/25 Javascript
vue.js将时间戳转化为日期格式的实现代码
2018/06/05 Javascript
新手简单了解vue
2019/05/29 Javascript
layui table 表格上添加日期控件的两种方法
2019/09/28 Javascript
详解JavaScript 高阶函数
2020/09/14 Javascript
手把手教你如何编译打包video.js
2020/12/09 Javascript
python里使用正则表达式的组嵌套实例详解
2017/10/24 Python
python ipset管理 增删白名单的方法
2019/01/14 Python
Python 实现数据结构中的的栈队列
2019/05/16 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
2019/08/21 Python
使用python将excel数据导入数据库过程详解
2019/08/27 Python
VSCode中自动为Python文件添加头部注释
2019/11/14 Python
Python第三方库安装缓慢的解决方法
2021/02/06 Python
使用html5+css3来实现slider切换效果告别javascript+css
2013/01/08 HTML / CSS
英国豪华文具和皮具配件经典老品牌:Smythson(斯迈森)
2018/04/19 全球购物
英语系本科生个人求职信
2013/09/21 职场文书
保健品市场营销方案
2014/03/31 职场文书
我有一个梦想演讲稿
2014/05/05 职场文书
文明美德伴我成长演讲稿
2014/05/12 职场文书
python如何查找列表中元素的位置
2022/05/30 Python