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 相关文章推荐
js 页面关闭前的出现提示的实现代码
May 25 Javascript
Jquery异步请求数据实例代码
Dec 28 Javascript
JS获取键盘上任意按键的值(实例代码)
Nov 12 Javascript
使用D3.js创建物流地图的示例代码
Jan 27 Javascript
Node.js实现mysql连接池使用事务自动回收连接的方法示例
Feb 03 Javascript
Material(包括Material Icon)在Angular2中的使用详解
Feb 11 Javascript
Angular2之二级路由详解
Aug 31 Javascript
JavaScript监听触摸事件代码实例
Dec 30 Javascript
JavaScript canvas绘制渐变颜色的矩形
Feb 18 Javascript
微信小程序搜索框样式并实现跳转到搜索页面(小程序搜索功能)
Mar 10 Javascript
jquery实现图片放大镜效果
Dec 23 jQuery
原生JavaScript实现购物车
Jan 10 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
用PHPdig打造属于你自己的Google[图文教程]
2007/02/14 PHP
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
php命令行使用方法和命令行参数说明
2014/04/08 PHP
PHP中exec与system用法区别分析
2014/09/22 PHP
PHP设计模式之观察者模式定义与用法分析
2019/04/04 PHP
jQuery 渐变下拉菜单
2009/12/15 Javascript
js实现简单计算器
2015/11/22 Javascript
url中的特殊符号有什么含义(推荐)
2016/06/17 Javascript
AngularJS入门教程之ng-class 指令用法
2016/08/01 Javascript
详解基于angular路由的requireJs按需加载js
2017/01/20 Javascript
详解JavaScript对象的深浅复制
2017/03/30 Javascript
微信小程序wx:for循环的实例详解
2018/10/07 Javascript
简化版的vue-router实现思路详解
2018/10/19 Javascript
Element-ui自定义table表头、修改列标题样式、添加tooltip、:render-header使用
2019/04/11 Javascript
JavaScript遍历数组的方法代码实例
2020/01/14 Javascript
Angular处理未可知异常错误的方法详解
2021/01/17 Javascript
[02:39]DOTA2英雄基础教程 极限穿梭编织者
2013/12/05 DOTA
python基础教程之循环介绍
2014/08/29 Python
python实现在目录中查找指定文件的方法
2014/11/11 Python
Python中用startswith()函数判断字符串开头的教程
2015/04/07 Python
pygame学习笔记(5):游戏精灵
2015/04/15 Python
Python中优化NumPy包使用性能的教程
2015/04/23 Python
Python实现从URL地址提取文件名的方法
2015/05/15 Python
通过Python实现自动填写调查问卷
2017/09/06 Python
Python 字符串与二进制串的相互转换示例
2018/07/23 Python
详解如何将python3.6软件的py文件打包成exe程序
2018/10/09 Python
解决nohup执行python程序log文件写入不及时的问题
2019/01/14 Python
Python内置random模块生成随机数的方法
2019/05/31 Python
由面试题加深对Django的认识理解
2019/07/19 Python
python分割一个文本为多个文本的方法
2019/07/22 Python
Python实现鼠标自动在屏幕上随机移动功能
2020/03/14 Python
公证委托书大全
2014/04/04 职场文书
看上去很美观后感
2015/06/10 职场文书
冰雪公主观后感
2015/06/16 职场文书
文明礼仪主题班会
2015/08/13 职场文书
win11怎么消除图标小盾牌?win11消除图标小盾牌解决方法
2022/08/05 数码科技