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 相关文章推荐
学习ExtJS table布局
Oct 08 Javascript
JavaScript replace(rgExp,fn)正则替换的用法
Mar 04 Javascript
60个很实用的jQuery代码开发技巧收集
Dec 15 Javascript
基于javascript实现checkbox复选框实例代码
Jan 28 Javascript
浅谈javascript中的加减时间
Jul 12 Javascript
AngularJs bootstrap搭载前台框架——js控制部分
Sep 01 Javascript
微信小程序 Nginx环境配置详细介绍
Feb 14 Javascript
解决vue处理axios post请求传参的问题
Mar 05 Javascript
在小程序/mpvue中使用flyio发起网络请求的方法
Sep 13 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【圆形情况】
Dec 13 Javascript
微信小程序 多行文本显示...+显示更多按钮和收起更多按钮功能
Sep 26 Javascript
vue 表单输入框不支持focus及blur事件的解决方案
Nov 17 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
php smarty模版引擎中变量操作符及使用方法
2009/12/11 PHP
PHP实现将优酷土豆腾讯视频html地址转换成flash swf地址的方法
2017/08/04 PHP
PHP实现重载的常用方法实例详解
2017/10/18 PHP
PHP中的访问修饰符简单比较
2019/02/02 PHP
2020最新版 PhpStudy V8.1版本下载安装使用详解
2020/10/30 PHP
Javascript中的变量使用说明
2010/05/18 Javascript
javascript实现div浮动在网页最顶上并带关闭按钮效果实例
2013/08/13 Javascript
什么是cookie?js手动创建和存储cookie
2014/05/27 Javascript
TypeScript具有的几个不同特质
2015/04/07 Javascript
拥Bootstrap入怀——导航栏篇
2016/05/30 Javascript
微信小程序实现tab和swiper切换结合效果
2020/07/17 Javascript
详解Vue中的scoped及穿透方法
2019/04/18 Javascript
Vue动态组件和异步组件原理详解
2019/05/06 Javascript
详解vue实现坐标拾取器功能示例
2020/11/18 Vue.js
echarts浮动显示单位的实现方法示例
2020/12/04 Javascript
用Python的Flask框架结合MySQL写一个内存监控程序
2015/11/07 Python
python 定义n个变量方法 (变量声明自动化)
2018/11/10 Python
python3安装speech语音模块的方法
2018/12/24 Python
在Python文件中指定Python解释器的方法
2019/02/18 Python
pyqt5 获取显示器的分辨率的方法
2019/06/18 Python
django项目中使用手机号登录的实例代码
2019/08/15 Python
python中的逆序遍历实例
2019/12/25 Python
如何提高python 中for循环的效率
2020/04/15 Python
pyecharts动态轨迹图的实现示例
2020/04/17 Python
Python生成器generator原理及用法解析
2020/07/20 Python
L’AGENCE官网:加州女装品牌
2018/06/03 全球购物
基层党组织公开承诺书
2014/03/28 职场文书
老师对学生的评语
2014/04/18 职场文书
卫生标语大全
2014/06/21 职场文书
大学感恩节活动策划方案
2014/10/11 职场文书
世界遗产导游词
2015/02/13 职场文书
高一化学教学反思
2016/02/22 职场文书
2019朋友新婚祝福语精选
2019/10/10 职场文书
JAVA SpringMVC实现自定义拦截器
2022/03/16 Python
win10电脑双屏显示一个黑屏怎么办?win10电脑双屏显示一个黑屏解决方法
2022/07/15 数码科技
Nginx如何获取自定义请求header头和URL参数详解
2022/07/23 Servers