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 相关文章推荐
{}与function(){}选用空对象{}来存放keyValue
May 23 Javascript
JavaScript操纵窗口的方法小结
Jun 28 Javascript
体验jQuery和AngularJS的不同点及AngularJS的迷人之处
Feb 02 Javascript
50 个 jQuery 插件可将你的网站带到另外一个高度
Apr 26 Javascript
jQuery简单创建节点的方法
Sep 09 Javascript
微信小程序 配置文件详细介绍
Dec 14 Javascript
JS碰撞运动实现方法详解
Dec 15 Javascript
Angular.js指令学习中一些重要属性的用法教程
May 24 Javascript
详解处理bootstrap4不支持远程静态框问题
Jul 20 Javascript
JavaScript实现预览本地上传图片功能完整示例
Mar 08 Javascript
js实现一款简单踩白块小游戏(曾经很火)
Dec 02 Javascript
基于JS判断对象是否是数组
Jan 10 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
php5.3 不支持 session_register() 此函数已启用的解决方法
2013/11/12 PHP
php实现粘贴截图并完成上传功能
2015/05/17 PHP
php使用ffmpeg获取视频信息并截图的实现方法
2016/05/03 PHP
Yii2配置Nginx伪静态的方法
2017/05/05 PHP
php简单生成一组与多组随机字符串的方法
2017/05/09 PHP
JS中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
2008/11/03 Javascript
XENON基于JSON变种
2010/07/27 Javascript
js汉字排序问题 支持中英文混排,兼容各浏览器,包括CHROME
2011/12/20 Javascript
Javascript浅谈之引用类型
2013/12/18 Javascript
js获取 type=radio 值的方法
2014/05/09 Javascript
JavaScript运行机制之事件循环(Event Loop)详解
2014/10/10 Javascript
jQuery延迟加载图片插件Lazy Load使用指南
2015/03/25 Javascript
javascript实现C语言经典程序题
2015/11/29 Javascript
JavaScript实现显示函数调用堆栈的方法
2016/04/21 Javascript
JavaScript常见的五种数组去重的方式
2016/12/15 Javascript
详解nodejs 文本操作模块-fs模块(一)
2016/12/22 NodeJs
微信小程序 页面滑动事件的实例详解
2017/10/12 Javascript
Angular如何在应用初始化时运行代码详解
2018/06/11 Javascript
vue监听对象及对象属性问题
2018/08/20 Javascript
对angular4子路由&辅助路由详解
2018/10/09 Javascript
Java Varargs 可变参数用法详解
2020/01/28 Javascript
[03:17]DOTA2英雄基础教程 剧毒术士
2013/12/12 DOTA
Python实现抓取百度搜索结果页的网站标题信息
2015/01/22 Python
Python程序中设置HTTP代理
2016/11/06 Python
Python配置mysql的教程(推荐)
2017/10/13 Python
浅谈PyQt5 的帮助文档查找方法,可以查看每个类的方法
2019/06/25 Python
python3.7简单的爬虫实例详解
2019/07/08 Python
解决Python3用PIL的ImageFont输出中文乱码的问题
2019/08/22 Python
python 创建一维的0向量实例
2019/12/02 Python
使用Python发现隐藏的wifi
2020/03/04 Python
CSS3 2D模拟实现摩天轮旋转效果
2016/11/16 HTML / CSS
请问软件开发中的设计模式你会使用哪些
2015/05/13 面试题
电子信息专业学生自荐信
2013/11/09 职场文书
中餐厅经理岗位职责
2014/04/11 职场文书
大学生志愿者心得体会
2016/01/15 职场文书
php中pcntl_fork详解
2021/04/01 PHP