基于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实现点击链接弹出"图片另存为"而不是直接打开
Aug 15 Javascript
仿新浪微博返回顶部的jquery实现代码
Oct 01 Javascript
JS操作Cookies的小例子
Oct 15 Javascript
window.open 以post方式传递参数示例代码
Feb 27 Javascript
JavaScript常用脚本汇总(三)
Mar 04 Javascript
JavaScript实现文字跟随鼠标特效
Aug 06 Javascript
jQuery绑定事件on()与弹窗的简要概述
Apr 27 Javascript
jQuery快速高效制作网页交互特效
Feb 24 Javascript
分享一个精简的vue.js 图片lazyload插件实例
Mar 13 Javascript
深究AngularJS中$sce的使用
Jun 12 Javascript
Vue单文件组件基础模板小结
Aug 10 Javascript
Vue路由前后端设计总结
Aug 06 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 Web开发MVC框架的Smarty使用说明
2013/04/19 PHP
迁移PHP版本到PHP7
2015/02/06 PHP
php实现统计目录文件大小的函数
2015/12/25 PHP
PHP实现伪静态方法汇总
2016/01/13 PHP
php简单随机字符串生成方法示例
2017/04/19 PHP
2017年最好用的9个php开发工具推荐(超好用)
2017/10/23 PHP
PHP的RSA加密解密方法以及开发接口使用
2018/02/11 PHP
原来Jquery.load的方法可以一直load下去
2011/03/28 Javascript
跨浏览器的事件对象介绍
2012/06/27 Javascript
JavaScript中把数字转换为字符串的程序代码
2013/06/19 Javascript
javascript使用call调用微信API
2014/12/15 Javascript
详解jQuery的表单验证插件--Validation
2016/12/21 Javascript
基于NodeJS+MongoDB+AngularJS+Bootstrap开发书店案例分析
2017/01/12 NodeJs
vue 实现 tomato timer(蕃茄钟)实例讲解
2017/07/24 Javascript
js实现方块上下左右移动效果
2017/08/17 Javascript
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
关于Google发布的JavaScript代码规范你要知道哪些
2018/04/04 Javascript
webpack打包多页面的方法
2018/11/30 Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
2018/12/03 Javascript
Vue性能优化的方法
2020/07/30 Javascript
[40:04]Secret vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.23
2019/09/05 DOTA
Python之读取TXT文件的方法小结
2018/04/27 Python
python3 pygame实现接小球游戏
2019/05/14 Python
Scrapy基于scrapy_redis实现分布式爬虫部署的示例
2020/09/29 Python
html5实现canvas阴影效果示例
2014/05/07 HTML / CSS
澳大利亚旅游网站:Lastminute
2017/08/07 全球购物
可持续木材、生态和铝制太阳镜:Proof Eyewear
2019/07/24 全球购物
某公司的.net工程师面试题笔试题
2013/11/22 面试题
《路旁的橡树》教学反思
2014/04/07 职场文书
企业人事任命书
2014/06/05 职场文书
研究生简历自我评价范文
2014/09/13 职场文书
第二批党的群众路线教育实践活动总结报告
2014/10/30 职场文书
2015年党员创先争优承诺书
2015/01/22 职场文书
公司借条范本
2015/05/25 职场文书
面试必问:圣杯布局和双飞翼布局的区别
2021/05/13 HTML / CSS
《我的美好婚事》动画化决定纪念插画与先导PV公开
2022/04/06 日漫