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 相关文章推荐
web 页面分页打印的实现
Jun 22 Javascript
js 代码集(学习js的朋友可以看下)
Jul 22 Javascript
jQuery-serialize()输出序列化form表单值的方法
Dec 26 Javascript
js遍历、动态的添加数据的小例子
Jun 22 Javascript
jquery通过visible来判断标签是否显示或隐藏
May 08 Javascript
判断日期是否能跨月查询的js代码
Jul 25 Javascript
AngularJS读取JSON及XML文件的方法示例
May 25 Javascript
详解有关easyUI的拖动操作中droppable,draggable用法例子
Jun 03 Javascript
JSONP原理及应用实例详解
Sep 13 Javascript
vuedraggable+element ui实现页面控件拖拽排序效果
Jul 29 Javascript
vue cli使用融云实现聊天功能的实例代码
Apr 19 Javascript
手动实现vue2.0的双向数据绑定原理详解
Feb 06 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
一个更简单的无限级分类菜单代码
2007/01/16 PHP
PHP实现根据数组某个键值大小进行排序的方法
2018/03/13 PHP
详解Laravel服务容器的绑定与解析
2019/11/05 PHP
asp javascript 实现关闭窗口时保存数据的办法
2007/11/24 Javascript
通过event对象的fromElement属性解决热区设置主实体的一个bug
2008/12/22 Javascript
js判断输入是否为正整数、浮点数等数字的函数代码
2010/11/17 Javascript
在iframe里的页面编写js,实现在父窗口上创建动画效果展开和收缩的div(不变动iframe父窗口代码)
2011/12/20 Javascript
javascript椭圆旋转相册实现代码
2012/01/16 Javascript
jQuery之日期选择器的深入解析
2013/06/19 Javascript
快速查找数组中的某个元素并返回下标示例
2013/09/03 Javascript
js跨域请求的5中解决方式
2015/07/02 Javascript
jQuery实现无限往下滚动效果代码
2016/04/16 Javascript
基于JS实现EOS隐藏错误提示层代码
2016/04/25 Javascript
Node.js实现文件上传
2016/07/05 Javascript
canvas滤镜效果实现代码
2017/02/06 Javascript
如何重置vue打印变量的显示方式
2017/12/06 Javascript
详解基于electron制作一个node压缩图片的桌面应用
2019/01/29 Javascript
vue中使用WX-JSSDK的两种方法(推荐)
2020/01/18 Javascript
vue-cli创建的项目中的gitHooks原理解析
2020/02/14 Javascript
2分钟实现一个Vue实时直播系统的示例代码
2020/06/05 Javascript
Element Input输入框的使用方法
2020/07/26 Javascript
python实现网页链接提取的方法分享
2014/02/25 Python
Python动态加载模块的3种方法
2014/11/22 Python
Python实现一个简单的MySQL类
2015/01/07 Python
在Linux系统上通过uWSGI配置Nginx+Python环境的教程
2015/12/25 Python
解决Python print 输出文本显示 gbk 编码错误问题
2018/07/13 Python
python日期相关操作实例小结
2019/06/24 Python
12个步骤教你理解Python装饰器
2019/07/01 Python
在SQLite-Python中实现返回、查询中文字段的方法
2019/07/17 Python
Python对接六大主流数据库(只需三步)
2019/07/31 Python
Alpine安装Python3依赖出现的问题及解决方法
2020/12/25 Python
县政府领导班子“四风”方面突出问题整改措施
2014/09/23 职场文书
满月酒邀请函
2015/01/30 职场文书
主持人开场白台词
2015/05/29 职场文书
2016年教师师德师风心得体会
2016/01/12 职场文书
Win11绿屏怎么办?Win11绿屏死机的解决方法
2021/11/21 数码科技