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 相关文章推荐
jquerymobile checkbox及时刷新才能获取其准确值
Apr 14 Javascript
javascript ready和load事件的区别示例介绍
Aug 30 Javascript
回车直接实现点击某按钮的效果即触发单击事件
Feb 27 Javascript
javascript等号运算符使用详解
Apr 16 Javascript
jQueryUI Datepicker组件设置日期高亮
Oct 13 Javascript
vue双花括号的使用方法 附练习题
Nov 07 Javascript
详解在Vue中使用TypeScript的一些思考(实践)
Jul 06 Javascript
AngularJS实现与后台服务器进行交互的示例讲解
Aug 13 Javascript
JS监听滚动和id自动定位滚动
Dec 18 Javascript
uni-app自定义导航栏按钮|uniapp仿微信顶部导航条功能
Nov 12 Javascript
微信小程序间使用navigator跳转传值问题实例分析
Mar 27 Javascript
小程序选项卡以及swiper套用(跨页面)
Jun 19 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的curl实现get和post的代码
2008/08/23 PHP
php旋转图片90度的方法
2013/11/07 PHP
php 从一个数组中随机的取出若干个不同的数实例
2016/12/31 PHP
php使用Jpgraph创建柱状图展示年度收支表效果示例
2017/02/15 PHP
php7 新增功能实例总结
2020/05/25 PHP
对textarea框的代码调试,而且功能上使用非常方便,酷
2006/06/30 Javascript
JavaScript日历实现代码
2010/09/12 Javascript
网页打开自动最大化的js代码
2012/08/22 Javascript
用JavaScript实现动画效果的方法
2013/07/20 Javascript
js截取固定长度的中英文字符的简单实例
2013/11/22 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
Node.js文件操作方法汇总
2016/03/22 Javascript
JS传值出现中文参数乱码的解决方法
2016/06/30 Javascript
jQuery选择器之表单元素选择器详解
2017/09/19 jQuery
微信小程序倒计时功能实现代码
2017/11/09 Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
2019/03/28 Javascript
JS实现图片轮播效果实例详解【可自动和手动】
2019/04/04 Javascript
小程序server请求微信服务器超时的解决方法
2019/05/21 Javascript
Javascript和jquery在selenium的使用过程
2019/10/31 jQuery
总结Python中逻辑运算符的使用
2015/05/13 Python
Python实现网络端口转发和重定向的方法
2016/09/19 Python
python django使用haystack:全文检索的框架(实例讲解)
2017/09/27 Python
Python实现获取照片拍摄日期并重命名的方法
2017/09/30 Python
对python sklearn one-hot编码详解
2018/07/10 Python
Python生成器generator用法示例
2018/08/10 Python
python sorted函数原理解析及练习
2020/02/10 Python
Python-opencv实现红绿两色识别操作
2020/06/04 Python
Html5 canvas实现粒子时钟的示例代码
2018/09/06 HTML / CSS
2014年乡镇妇联工作总结
2014/12/02 职场文书
归元寺导游词
2015/02/06 职场文书
2015年五一劳动节活动总结
2015/02/09 职场文书
爱国主义影片观后感
2015/06/18 职场文书
学习弘扬焦裕禄精神心得体会
2016/01/23 职场文书
因个人工作失误检讨书
2019/06/21 职场文书
Java基于字符界面的简易收银台
2021/06/26 Java/Android
SQL中的三种去重方法小结
2021/11/01 SQL Server