JavaScript 原型继承之构造函数继承


Posted in Javascript onAugust 26, 2011

上回说到《JavaScript 原型继承之基础机制》,这一篇将具体说说构造函数的继承。

从一个简单的示例开始,创建描述人类的 People 构造函数:

function People(){ 
this.race = '愚蠢的人类'; 
}

然后,创建描述黄种人的 Yellow 构造函数:
function Yellow(name, skin){ 
this.name = name; 
this.skin = skin; 
}

要使得黄种人 Yellow 能继承人类 People 对象,在 JavaScript 中可以通过多种方式模拟实现。

1、对象冒充(Object Masquerading)

对象冒充,简单地说就是把一个定义抽象类的构造函数当作常规函数使用,实现伪继承:

function Yellow(name, skin) { 
this._extend = People; 
this._extend(); 
delete this._extend; //删除对 People 的引用 
this.name = name; 
this.skin = skin; 
} 
//实例化 yellow1 
var yellow1 = new Yellow('小明', '黄皮肤'); 
console.log(yellow1.name); //小明 
console.log(yellow1.race); //愚蠢的人类

在这段代码中,为 Yellow 添加私有方法 _extend,由于函数本身只是以引用的形式存在,执行时会自动调用 People方法,并传入 Yellow 构造函数的 name 参数。而 Yellow 对象的自身属性和方法,必须在上述过程结束,清空对外部方法的引用后再进行定义。

注:通过对象冒充可以实现多重继承

2、call / apply 方法

通过 call / apply 方法实现继承可能更为简单,不需要任何繁琐的操作:

function Yellow(name, skin) { 
People.apply(this, arguments); 
this.name = name; 
this.skin = skin; 
} 
//实例化 yellow2 
var yellow2 = new Yellow('大卫', '黑皮肤') 
console.log(yellow2.name); //大卫 
console.log(yellow2.race); //愚蠢的人类 
这里为 apply 传入 arguments 数组,也可以使用 new Array 或字面量数组。

3、原型链(Prototype Chaining)

第一种原型继承方法是把对象的原型指向父类的某个实例:

Yellow.prototype = new People(); 
Yellow.prototype.constructor = Yellow; //初始的 prototype 被完全清空,所以最好将 constructor 重置 
var yellow3 = new Yellow('小王', '黄皮肤'); 
console.log(yellow3.race); //愚蠢的人类

以上代码可以这样反向理解,yellow3 实例本身找不到 race 属性,而它原型上的 race 属性又恰好是 People 对象的实例的 race 属性。

如果对于 People 对象来说,其属性写入了原型中,则无需实例化,只需将 Yellow 的 prototype 属性指向 People的 prototype 属性:

function People(){}; 
People.prototype.race = '愚蠢的人类'; 
Yellow.prototype = People.prototype; 
Yellow.prototype.constructor = Yellow;

这样做不进行实例化操作,只是指针的改变,非常环保。但由于引用类型的关系,Yellow 和 People 指向了同一个原型对象,也就是说对 Yellow.prototype.constructor 的修改实际上破坏了 People 的原型对象。

既然如此,可以借助一个空的中继对象,绕过父类的原型:

var F = function(){}; 
F.prototype = People.prototype; 
Yellow.prototype = new F(); 
Yellow.prototype.constructor = Yellow;
Javascript 相关文章推荐
超级24小时弹窗代码 24小时退出弹窗代码 100%弹窗代码(IE only)
Jun 11 Javascript
jQuery帮助之筛选查找 children([expr])
Jan 31 Javascript
JavaScript中的条件判断语句使用详解
Jun 03 Javascript
JS本地刷新返回上一页代码
Jul 25 Javascript
jQuery简单实现中间浮窗效果
Sep 04 Javascript
基于jQuery实现表格的排序
Dec 02 Javascript
javascript常用的设计模式
Feb 09 Javascript
使用grunt合并压缩js和css文件的方法
Mar 02 Javascript
基于Node的React图片上传组件实现实例代码
May 10 Javascript
vue.js实现备忘录功能的方法
Jul 10 Javascript
JavaScript实现AOP详解(面向切面编程,装饰者模式)
Dec 19 Javascript
Angular4 反向代理Details实践
May 30 Javascript
JavaScript原型继承之基础机制分析
Aug 26 #Javascript
自己动手开发jQuery插件教程
Aug 25 #Javascript
JQuery里面的几种选择器 查找满足条件的元素$("#控件ID")
Aug 23 #Javascript
基于JQuery的Select选择框的华丽变身
Aug 23 #Javascript
MooTools 页面滚动浮动层智能定位实现代码
Aug 23 #Javascript
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
Aug 23 #Javascript
jQuery页面滚动浮动层智能定位实例代码
Aug 23 #Javascript
You might like
php学习笔记 [预定义数组(超全局数组)]
2011/06/09 PHP
PHP FOR MYSQL 代码生成助手(根据Mysql里的字段自动生成类文件的)
2011/07/23 PHP
PHP imagecreatefrombmp 从BMP文件或URL新建一图像
2012/07/16 PHP
php对象和数组相互转换的方法
2015/05/12 PHP
PHP MYSQL简易交互式站点开发
2016/12/27 PHP
在textarea中显示html页面的javascript代码
2007/04/20 Javascript
js下用gb2312编码解码实现方法
2009/12/31 Javascript
Extjs4 Treegrid 使用心得分享(经验篇)
2013/07/01 Javascript
node.js中使用socket.io的方法
2014/12/15 Javascript
基于jquery实现鼠标滚轮驱动的图片切换效果
2015/10/26 Javascript
JS上传图片预览插件制作(兼容到IE6)
2016/08/07 Javascript
vue项目中使用axios上传图片等文件操作
2017/11/02 Javascript
解决使用vue.js路由后失效的问题
2018/03/17 Javascript
JavaScript函数apply()和call()用法与异同分析
2018/08/10 Javascript
微信小程序实现的点击按钮 弹出底部上拉菜单功能示例
2018/12/20 Javascript
深入了解Hybrid App技术的相关知识
2019/07/17 Javascript
JS实现关闭小广告特效
2021/01/29 Javascript
JavaScript 替换所有匹配内容及正则替换方法
2020/02/12 Javascript
javascript canvas检测小球碰撞
2020/04/17 Javascript
[10:53]2018DOTA2国际邀请赛寻真——EG
2018/08/11 DOTA
零基础写python爬虫之爬虫框架Scrapy安装配置
2014/11/06 Python
深入理解Django中内置的用户认证
2017/10/06 Python
Python3中的列表,元组,字典,字符串相关知识小结
2017/11/10 Python
python ansible服务及剧本编写
2017/12/29 Python
Python实现求解括号匹配问题的方法
2018/04/17 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
在django中使用apscheduler 执行计划任务的实现方法
2020/02/11 Python
使用python操作lmdb对数据读取的实例
2020/12/11 Python
SmartBuyGlasses台湾:名牌眼镜,名牌太阳眼镜及隐形眼镜
2017/01/04 全球购物
社区党员先进事迹
2014/01/22 职场文书
优秀技术工人先进材料
2014/02/17 职场文书
课内比教学心得体会
2014/09/09 职场文书
2014年库房工作总结
2014/11/26 职场文书
Java spring单点登录系统
2021/09/04 Java/Android
使用refresh_token实现无感刷新页面
2022/04/26 Javascript
TS 类型收窄教程示例详解
2022/09/23 Javascript