Javascript面向对象编程(三) 非构造函数的继承


Posted in Javascript onAugust 28, 2011

今天是最后一个部分,介绍不使用构造函数实现"继承"。
一、什么是"非构造函数"的继承?
比如,现在有一个对象,叫做"中国人"。

var Chinese = { 


nation:'中国' 

};

还有一个对象,叫做"医生"。
var Doctor ={ 


career:'医生' 

}

请问怎样才能让"医生"去继承"中国人",也就是说,我怎样才能生成一个"中国医生"的对象?
这里要注意,这两个对象都是普通对象,不是构造函数,无法使用构造函数方法实现"继承"。
二、object()方法
json格式的发明人Douglas Crockford,提出了一个object()函数,可以做到这一点。
function object(o) { 


function F() {} 


F.prototype = o; 


return new F(); 

}

这个object()函数,其实只做一件事,就是把子对象的prototype属性,指向父对象,从而使得子对象与父对象连在一起。
使用的时候,第一步先在父对象的基础上,生成子对象:

var Doctor = object(Chinese);
然后,再加上子对象本身的属性:

Doctor.career = '医生';
这时,子对象已经继承了父对象的属性了。

alert(Doctor.nation); //中国
三、浅拷贝
除了使用"prototype链"以外,还有另一种思路:把父对象的属性,全部拷贝给子对象,也能实现继承。
下面这个函数,就是在做拷贝:

function extendCopy(p) { 


var c = {}; 


for (var i in p) { 



c[i] = p[i]; 


} 


c.uber = p; 


return c; 

}

使用的时候,这样写:
var Doctor = extendCopy(Chinese); 

Doctor.career = '医生'; 

alert(Doctor.nation); // 中国

但是,这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。
请看,现在给Chinese添加一个"出生地"属性,它的值是一个数组。

Chinese.birthPlaces = ['北京','上海','香港'];
通过extendCopy()函数,Doctor继承了Chinese。

var Doctor = extendCopy(Chinese);
然后,我们为Doctor的"出生地"添加一个城市:

Doctor.birthPlaces.push('厦门');
发生了什么事?Chinese的"出生地"也被改掉了!

alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门

alert(Chinese.birthPlaces); //北京, 上海, 香港, 厦门
所以,extendCopy()只是拷贝基本类型的数据,我们把这种拷贝叫做"浅拷贝"。这是早期jQuery实现继承的方式。
四、深拷贝
所谓"深拷贝",就是能够实现真正意义上的数组和对象的拷贝。它的实现并不难,只要递归调用"浅拷贝"就行了。

function deepCopy(p, c) { 


var c = c || {}; 


for (var i in p) { 



if (typeof p[i] === 'object') { 




c[i] = (p[i].constructor === Array) ? [] : {}; 




deepCopy(p[i], c[i]); 



} else { 




 c[i] = p[i]; 



} 


} 


return c; 

}

使用的时候这样写:

var Doctor = deepCopy(Chinese);
现在,给父对象加一个属性,值为数组。然后,在子对象上修改这个属性:

Chinese.birthPlaces = ['北京','上海','香港']; 

Doctor.birthPlaces.push('厦门');

这时,父对象就不会受到影响了。
alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门 

alert(Chinese.birthPlaces); //北京, 上海, 香港

目前,jQuery库使用的就是这种继承方法。
(完)
Javascript 相关文章推荐
获取页面高度,窗口高度,滚动条高度等参数值getPageSize,getPageScroll
Sep 22 Javascript
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
Feb 04 Javascript
用dtree实现树形菜单 dtree使用说明
Oct 17 Javascript
jquery的选择器的使用技巧之如何选择input框
Sep 22 Javascript
js获取隐藏元素宽高的实现方法
May 19 Javascript
jQuery实现花式轮播之圣诞节礼物传送效果
Dec 25 Javascript
详解vue项目中使用token的身份验证的简单实践
Mar 08 Javascript
微信小程序如何刷新当前界面的实现方法
Jun 07 Javascript
json 带斜杠时如何解析的实现
Aug 12 Javascript
Vue 解决多级动态面包屑导航的问题
Nov 04 Javascript
vue 移动端记录页面浏览位置的方法
Mar 11 Javascript
使用js原生实现年份轮播选择效果实例
Jan 12 Javascript
Javascript面向对象编程(二) 构造函数的继承
Aug 28 #Javascript
Javascript 面向对象编程(一) 封装
Aug 28 #Javascript
Javascript继承机制的设计思想分享
Aug 28 #Javascript
有关JavaScript的10个怪癖和秘密分享
Aug 28 #Javascript
JS面向对象编程浅析
Aug 28 #Javascript
用JS实现一个TreeMenu效果分享
Aug 28 #Javascript
JS target与currentTarget区别说明
Aug 28 #Javascript
You might like
献给php初学者(入门学习经验谈)
2010/10/12 PHP
PHP 安全检测代码片段(分享)
2013/07/05 PHP
php自定义session示例分享
2014/04/22 PHP
php文件系统处理方法小结
2016/05/23 PHP
PHP面向对象程序设计中的self、static、parent关键字用法分析
2019/08/14 PHP
快速保存网页中所有图片的方法
2006/06/23 Javascript
用Javascript做flash做的事..才完成的一个类.Auntion Action var 0.1
2007/02/23 Javascript
javascript中获取选中对象的类型
2007/04/02 Javascript
jMessageBox 基于jQuery的窗口插件
2009/12/09 Javascript
jQuery实现回车键(Enter)切换文本框焦点的代码实例
2014/05/05 Javascript
JavaScript实现的伸展收缩型菜单代码
2015/10/14 Javascript
详解js中class的多种函数封装方法
2016/01/03 Javascript
jQuery实现带水平滑杆的焦点图动画插件
2016/03/08 Javascript
JS添加删除DIV的简单实例
2016/07/08 Javascript
javascript数组遍历的方法实例分析
2016/09/13 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
js实现登录注册框手机号和验证码校验(前端部分)
2017/09/28 Javascript
pm2 部署 node的三种方法示例
2017/10/20 Javascript
使用vue如何构建一个自动建站项目
2018/02/05 Javascript
详解vue移动端项目的适配(以mint-ui为例)
2018/08/17 Javascript
JS函数内部属性之arguments和this实例解析
2018/10/07 Javascript
详解小程序中h5页面onShow实现及跨页面通信方案
2019/05/30 Javascript
js中的this的指向问题详解
2019/08/29 Javascript
解决layer图标icon不加载的问题
2019/09/04 Javascript
使用localStorage替代cookie做本地存储
2019/09/25 Javascript
vuejs中父子组件之间通信方法实例详解
2020/01/17 Javascript
vscode调试node.js的实现方法
2020/03/22 Javascript
[01:02:20]Mineski vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
Python使用装饰器进行django开发实例代码
2018/02/06 Python
pycharm 激活码及使用方式的详细教程
2020/05/12 Python
爬虫代理的cookie如何生成运行
2020/09/22 Python
python eventlet绿化和patch原理
2020/11/21 Python
美国运动鞋和运动服零售商:Footaction
2017/04/07 全球购物
英国独特礼物想法和个性化礼物网站:notonthehighstreet.com
2018/04/16 全球购物
公司董事长岗位职责
2014/06/08 职场文书
就业意向协议书
2015/01/29 职场文书