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 DOM 学习第五章 表单简介
Feb 19 Javascript
JavaScript中instanceof与typeof运算符的用法及区别详细解析
Nov 19 Javascript
JavaScript返回网页中锚点数目的方法
Apr 03 Javascript
js完美解决IE6不支持position:fixed的bug
Apr 24 Javascript
JS+Canvas 实现下雨下雪效果
May 18 Javascript
echarts3 使用总结(绘制各种图表,地图)
Jan 05 Javascript
AngularJS实现tab选项卡的方法详解
Jul 05 Javascript
详解使用VUE搭建后台管理系统(vue-cli更新至3.0)
Aug 22 Javascript
JS实现的简单分页功能示例
Aug 23 Javascript
JS实现根据详细地址获取经纬度功能示例
Apr 16 Javascript
javascript实现抢购倒计时程序
Aug 26 Javascript
使用Webpack提升Vue.js应用程序的4种方法(翻译)
Oct 09 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
网页游戏开发入门教程三(简单程序应用)
2009/11/02 PHP
标准PHP的AES加密算法类
2015/03/12 PHP
PHP yii实现model添加默认值的方法(两种方法)
2016/11/10 PHP
解决laravel 表单提交-POST 异常的问题
2019/10/15 PHP
XP折叠菜单&仿QQ2006菜单
2006/12/16 Javascript
baidu博客的编辑友情链接的新的层窗口!经典~支持【FF】
2007/02/09 Javascript
需要做特殊处理的DOM元素属性的访问
2010/11/05 Javascript
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
2012/08/14 Javascript
JS 实现Table相同行的单元格自动合并示例代码
2013/08/27 Javascript
将input file的选择的文件清空的两种解决方案
2013/10/21 Javascript
jQuery如何实现点击页面获得当前点击元素的id或其他信息
2014/01/09 Javascript
用于deeplink的js方法(判断手机是否安装app)
2014/04/02 Javascript
js四舍五入数学函数round使用实例
2014/05/09 Javascript
Javascript中实现String.startsWith和endsWith方法
2015/06/10 Javascript
jQuery实现带滚动导航效果的全屏滚动相册实例
2015/06/19 Javascript
Javascript显示和隐藏ul列表的方法
2015/07/15 Javascript
jQuery实现点击弹出背景变暗遮罩效果实例代码
2016/06/24 Javascript
Javascript中级语法快速入手
2016/07/30 Javascript
angular2倒计时组件使用详解
2017/01/12 Javascript
JavaScript实现离开页面前提示功能【附jQuery实现方法】
2017/09/26 jQuery
详解javascript replace高级用法
2019/02/17 Javascript
原生JavaScript之es6中Class的用法分析
2020/02/23 Javascript
使用Python操作Elasticsearch数据索引的教程
2015/04/08 Python
Python 使用list和tuple+条件判断详解
2019/07/30 Python
Python count函数使用方法实例解析
2020/03/23 Python
Python爬虫之Selenium实现键盘事件
2020/12/04 Python
详解Python+Selenium+ChromeDriver的配置和问题解决
2021/01/19 Python
Python中正则表达式对单个字符,多个字符和匹配边界等使用
2021/01/27 Python
如何利用input事件来监听移动端的输入
2016/04/15 HTML / CSS
波兰品牌鞋履在线商店:Eastend.pl
2020/01/11 全球购物
应届护士推荐信
2013/11/16 职场文书
联欢晚会主持词
2014/03/25 职场文书
促销活动总结
2014/04/28 职场文书
SpringCloud的JPA连接PostgreSql的教程
2021/06/26 Java/Android
使用GO语言实现Mysql数据库CURD的简单示例
2021/08/07 Golang
云服务器部署 Web 项目的实现步骤
2022/06/28 Servers