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 相关文章推荐
JavaScript中双叹号(!!)作用示例介绍
Apr 10 Javascript
Angularjs 设置全局变量的方法总结
Oct 20 Javascript
Vue系列:通过vue-router如何传递参数示例
Jan 16 Javascript
ajax分页效果(bootstrap模态框)
Jan 23 Javascript
原生javascript移动端滑动banner效果
Mar 10 Javascript
详解React开发中使用require.ensure()按需加载ES6组件
May 12 Javascript
详解如何构建一个Angular6的第三方npm包
Sep 07 Javascript
JS数组求和的常用方法总结【5种方法】
Jan 14 Javascript
微信小程序云函数使用mysql数据库过程详解
Aug 07 Javascript
微信小程序自定义tabBar在uni-app的适配详解
Sep 30 Javascript
javascript中的相等操作符(==与===区别)
Dec 21 Javascript
vue前端工程的搭建
Mar 31 Vue.js
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
使用laravel和ECharts实现折线图效果的例子
2019/10/09 PHP
使用IE的地址栏来辅助调试Web页脚本
2007/03/08 Javascript
JavaScript 继承详解(四)
2009/07/13 Javascript
js控制table合并具体实现
2014/02/20 Javascript
JS+CSS实现仿触屏手机拨号盘界面及功能模拟完整实例
2015/05/16 Javascript
js实现无缝循环滚动
2020/06/23 Javascript
浅谈javascript中的Function和Arguments
2016/08/30 Javascript
原生js实现图片放大缩小计时器效果
2017/01/20 Javascript
使用Bootstrap美化按钮实例代码(demo)
2017/02/03 Javascript
jQuery Validate 校验多个相同name的方法
2017/05/18 jQuery
JS中Attr的用法详解
2017/10/09 Javascript
angular 实现的输入框数字千分位及保留几位小数点功能示例
2018/06/19 Javascript
在vue项目中引入vue-beauty操作方法
2019/02/11 Javascript
小程序数据通信方法大全(推荐)
2019/04/15 Javascript
vue操作动画的记录animate.css实例代码
2019/04/26 Javascript
js操作两个json数组合并、去重,以及删除某一项元素
2020/09/22 Javascript
Vue仿百度搜索功能
2020/12/28 Vue.js
[41:54]2018DOTA2亚洲邀请赛 4.1 小组赛A组加赛 TNC vs Liquid
2018/04/03 DOTA
[46:12]完美世界DOTA2联赛循环赛 DM vs Matador BO2第一场 11.04
2020/11/04 DOTA
JS设计模式之责任链模式实例详解
2018/02/03 Python
Python使用tkinter模块实现推箱子游戏
2019/10/08 Python
Python sklearn库实现PCA教程(以鸢尾花分类为例)
2020/02/24 Python
探索HTML5本地存储功能运用技巧
2016/03/02 HTML / CSS
德国机场停车位比较和预订网站:Ich-parke-billiger
2018/01/08 全球购物
理肤泉美国官网:La Roche-Posay
2018/01/17 全球购物
怎样声明子类
2013/07/02 面试题
数据库方面面试题
2012/04/22 面试题
工商管理系学生的自我评价分享
2013/11/29 职场文书
中学生自我鉴定
2014/02/04 职场文书
节能减耗标语
2014/06/21 职场文书
pycharm无法导入lxml的解决办法
2021/03/31 Python
解决SpringCloud Feign传对象参数调用失败的问题
2021/06/23 Java/Android
纯html+css实现Element loading效果
2021/08/02 HTML / CSS
Spring Boot 底层原理基础深度解析
2022/04/03 Java/Android
Windows下载并安装MySQL8.0.x 版本的完整教程
2022/04/10 MySQL
PyCharm 配置SSH和SFTP连接远程服务器
2022/05/11 Python