基于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 相关文章推荐
键盘控制事件应用教程大全
Nov 24 Javascript
浅谈JavaScript 的执行顺序
Aug 07 Javascript
JavaScript必知必会(七)js对象继承
Jun 08 Javascript
jQuery实现ToolTip元素定位显示功能示例
Nov 23 Javascript
详解前端路由实现与react-router使用姿势
Aug 07 Javascript
从零开始搭建webpack+react开发环境的详细步骤
May 18 Javascript
vue里input根据value改变背景色的实例
Sep 29 Javascript
JS根据json数组多个字段排序及json数组常用操作
Jun 06 Javascript
利用Vue-draggable组件实现Vue项目中表格内容的拖拽排序
Jun 07 Javascript
微信小程序swiper使用网络图片不显示问题解决
Dec 13 Javascript
关于vue 结合原生js 解决echarts resize问题
Jul 26 Javascript
微信小程序canvas实现签名功能
Jan 19 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
SWFUpload与CI不能正确上传识别文件MIME类型解决方法分享
2011/04/18 PHP
php中让上传的文件大小在上传前就受限制的两种解决方法
2013/06/24 PHP
PHP Curl多线程原理实例详解
2013/11/06 PHP
php文件上传的例子及参数详解
2013/12/12 PHP
kindeditor 加入七牛云上传的实例讲解
2017/11/12 PHP
详细解读php的命名空间(一)
2018/02/21 PHP
使用laravel的Eloquent模型如何获取数据库的指定列
2019/10/17 PHP
脚本安需导入(装载)的三种模式的对比
2007/06/24 Javascript
网页禁用右键实现代码(JavaScript代码)
2009/10/29 Javascript
Javascript中正则表达式的全局匹配模式分析
2011/04/26 Javascript
jquery用offset()方法获得元素的xy坐标
2014/09/06 Javascript
为JS扩展Array.prototype.indexOf引发的问题及解决办法
2015/01/21 Javascript
JS实现超简单的鼠标拖动效果
2015/11/02 Javascript
模板视图和AngularJS之间冲突的解决方法
2016/11/22 Javascript
详解node.js平台下Express的session与cookie模块包的配置
2017/04/26 Javascript
Vue2.5通过json文件读取数据的方法
2018/02/27 Javascript
vue中的模态对话框组件实现过程
2018/05/01 Javascript
Vue替代marquee标签超出宽度文字横向滚动效果
2019/12/09 Javascript
JavaScript实现矩形块大小任意缩放
2020/08/25 Javascript
解决python3中解压zip文件是文件名乱码的问题
2018/03/22 Python
Python 在字符串中加入变量的实例讲解
2018/05/02 Python
Python中的pathlib.Path为什么不继承str详解
2019/06/23 Python
Python求两点之间的直线距离(2种实现方法)
2019/07/07 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
2020/03/30 Python
关于Kotlin中SAM转换的那些事
2020/09/15 Python
提高python代码运行效率的一些建议
2020/09/29 Python
html5 桌面提醒:Notifycations应用介绍
2012/11/27 HTML / CSS
HTML5 通信API 跨域门槛将不再高、数据推送也不再是梦
2013/04/25 HTML / CSS
C#面试常见问题
2013/02/25 面试题
linux面试题参考答案(10)
2013/11/04 面试题
JavaScript获取当前url根目录(路径)
2014/02/19 面试题
咖啡厅创业计划书范本
2014/01/22 职场文书
车辆年审委托书范本
2014/09/18 职场文书
家庭贫困证明
2014/09/23 职场文书
考博导师推荐信范文
2015/03/27 职场文书
详解Python flask的前后端交互
2022/03/31 Python