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 相关文章推荐
记录几个javascript有关的小细节
Apr 02 Javascript
jquery中animate动画积累的解决方法
Oct 05 Javascript
jquery库文件略庞大用纯js替换jquery的方法
Aug 12 Javascript
javascript定义变量时加var与不加var的区别
Dec 22 Javascript
浅析Bootstrip的select控件绑定数据的问题
May 10 Javascript
手动用webpack搭建第一个ReactApp的示例
Apr 11 Javascript
vue打包之后生成一个配置文件修改接口的方法
Dec 09 Javascript
详解Vue调用手机相机和相册以及上传
May 05 Javascript
如何实现双向绑定mvvm的原理实现
May 28 Javascript
jQuery Datatables 动态列+跨列合并实现代码
Jan 30 jQuery
Vue toFixed保留两位小数的3种方式
Oct 23 Javascript
vue数据字典取键值项目的字典问题
Apr 12 Vue.js
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
ZF等常用php框架中存在的问题
2008/01/10 PHP
PHP curl_setopt()函数实例代码与参数分析
2011/06/02 PHP
PHP 面向对象程序设计(oop)学习笔记 (五) - PHP 命名空间
2014/06/12 PHP
php中in_array函数用法探究
2014/11/25 PHP
两个php日期控制类实例
2014/12/09 PHP
php封装的数据库函数与用法示例【参考thinkPHP】
2016/11/08 PHP
PHP页面跳转实现延时跳转的方法
2016/12/10 PHP
浅析php如何实现爬取数据原理
2018/09/27 PHP
PHP7使用ODBC连接SQL Server2008 R2数据库示例【基于thinkPHP5.1框架】
2019/05/06 PHP
jQuery checkbox全选/取消全选实现代码
2009/11/14 Javascript
jQuery筛选器children()案例详解(图文)
2013/02/17 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
html+js+highcharts绘制圆饼图表的简单实例
2016/08/04 Javascript
详解AngularJs HTTP响应拦截器实现登陆、权限校验
2017/04/11 Javascript
详解react-refetch的使用小例子
2019/02/15 Javascript
JS回调函数原理与用法详解【附PHP回调函数】
2019/07/20 Javascript
Element 默认勾选表格 toggleRowSelection的实现
2019/09/04 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
2019/09/25 Javascript
js实现复制粘贴的两种方法
2020/12/04 Javascript
[46:47]2014 DOTA2国际邀请赛中国区预选赛 DT VS HGT
2014/05/22 DOTA
查看Python安装路径以及安装包路径小技巧
2015/04/28 Python
Python实现数据库并行读取和写入实例
2017/06/09 Python
Python找出微信上删除你好友的人脚本写法
2018/11/01 Python
pandas通过索引进行排序的示例
2018/11/16 Python
详解Pandas之容易让人混淆的行选择和列选择
2019/07/10 Python
Django Celery异步任务队列的实现
2019/07/24 Python
使用Numpy对特征中的异常值进行替换及条件替换方式
2020/06/08 Python
澳大利亚便宜隐形眼镜购买网站:QUICKLENS Australia
2018/10/06 全球购物
美国正宗设计师眼镜在线零售商:EYEZZ
2019/03/23 全球购物
客运企业隐患排查工作方案
2014/06/06 职场文书
公司周年庆活动方案
2014/08/25 职场文书
赵乐秦在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
婚庆答谢词
2015/01/04 职场文书
500字作文之周记
2019/12/13 职场文书
Windows server 2012搭建FTP服务器
2022/04/29 Servers
Go 内联优化让程序员爱不释手
2022/06/21 Golang