基于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 相关文章推荐
从sohu弄下来的flash中展示图片的代码
Apr 27 Javascript
很全的显示阴历(农历)日期的js代码
Jan 01 Javascript
清除div下面的所有标签的方法
Feb 17 Javascript
JavaScript lastIndexOf方法入门实例(计算指定字符在字符串中最后一次出现的位置)
Oct 17 Javascript
js实现鼠标左右移动,图片也跟着移动效果
Jan 25 Javascript
jQuery阻止移动端遮罩层后页面滚动
Mar 15 Javascript
Angular 4依赖注入学习教程之ValueProvider的使用(七)
Jun 04 Javascript
BootStrap中Table隐藏后显示问题的实现代码
Aug 31 Javascript
javascript自定义事件功能与用法实例分析
Nov 08 Javascript
javascript实现fetch请求返回的统一拦截
Dec 22 Javascript
vue video和vue-video-player实现视频铺满教程
Oct 30 Javascript
React更新渲染原理深入分析
Dec 24 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导出Redis数据到另一个Redis中的代码
2014/03/12 PHP
PHP生成静态HTML页面最简单方法示例
2015/04/09 PHP
php实现用户登陆简单实例
2017/04/04 PHP
PHP实现递归的三种方法
2020/07/04 PHP
PNGHandler-借助JS让PNG图在IE下实现透明(包括背景图)
2007/08/31 Javascript
用js判断页面是否加载完成实现代码
2012/12/11 Javascript
基于dom编程中 动态创建与删除元素的使用
2013/04/17 Javascript
javascript实现图片循环渐显播放的方法
2015/02/24 Javascript
浅谈jQuery中ajaxPrefilter的应用
2016/08/01 Javascript
AngularGauge 属性解析详解
2016/09/06 Javascript
使用BootStrap实现表格隔行变色及hover变色并在需要时出现滚动条
2017/01/04 Javascript
ajax实现加载页面、删除、查看详细信息 bootstrap美化页面!
2017/03/14 Javascript
Nodejs进阶:express+session实现简易登录身份认证
2017/04/24 NodeJs
微信小程序开发之toast等弹框提示使用教程
2017/06/08 Javascript
使用Vue做一个简单的todo应用的三种方式的示例代码
2018/10/20 Javascript
微信小程序使用二次贝塞尔曲线画波浪
2018/12/25 Javascript
Vue 中 template 有且只能一个 root的原因解析(源码分析)
2020/04/11 Javascript
Python打造出适合自己的定制化Eclipse IDE
2016/03/02 Python
Python简单检测文本类型的2种方法【基于文件头及cchardet库】
2016/09/18 Python
python如何拆分含有多种分隔符的字符串
2018/03/20 Python
python散点图实例之随机漫步
2018/08/27 Python
用pycharm开发django项目示例代码
2018/10/24 Python
python 划分数据集为训练集和测试集的方法
2018/12/11 Python
python给微信好友定时推送消息的示例
2019/02/20 Python
python3常用的数据清洗方法(小结)
2019/10/31 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
2020/02/10 Python
python适合做数据挖掘吗
2020/06/16 Python
基于 Python 实践感知器分类算法
2021/01/07 Python
会计应届生的自荐信
2013/12/13 职场文书
入党思想汇报
2014/01/05 职场文书
金融管理毕业生求职信
2014/03/03 职场文书
债务授权委托书范本
2014/10/17 职场文书
普通党员整改措施
2014/10/24 职场文书
员工2014年度工作总结
2014/12/09 职场文书
检讨书格式范文
2015/05/07 职场文书
使用nginx配置访问wgcloud的方法
2021/06/26 Servers