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 相关文章推荐
一段利用WSH获取登录时间的jscript代码
May 11 Javascript
js 操作select相关方法函数
Dec 06 Javascript
基于jquery的监控数据是否发生改变
Apr 11 Javascript
使用GruntJS构建Web程序之安装篇
Jun 04 Javascript
微信浏览器内置JavaScript对象WeixinJSBridge使用实例
May 25 Javascript
Bootstrap表单简单实现代码
Mar 06 Javascript
Angular.Js中ng-include指令的使用与实现
May 07 Javascript
vue跨域解决方法
Oct 15 Javascript
IE11下CKEditor在Bootstrap Modal中下拉问题的解决
Sep 25 Javascript
JavaScript变量Dom对象的所有属性
Apr 30 Javascript
Vue父子组件传值的一些坑
Sep 16 Javascript
Map与WeakMap类型在JavaScript中的使用详解
Nov 18 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类常量的使用详解
2013/06/08 PHP
解析CI的AJAX分页 另类实现方法
2013/06/27 PHP
多个PHP中文字符串截取函数
2013/11/12 PHP
php自动识别文件编码并转换为UTF-8的方法
2014/06/12 PHP
PHP中Restful api 错误提示返回值实现思路
2016/04/12 PHP
JQuery的Validation插件中Remote验证的中文问题
2010/07/26 Javascript
javascript字符串拼接的效率问题
2010/12/25 Javascript
简单学习JavaScript中的for语句循环结构
2015/11/10 Javascript
react-router实现跳转传值的方法示例
2017/05/27 Javascript
Express框架之connect-flash详解
2017/05/31 Javascript
Vue中android4.4不兼容问题的解决方法
2018/09/04 Javascript
解决node-sass偶尔安装失败的方法小结
2018/12/05 Javascript
jquery实现下载图片功能
2019/07/18 jQuery
详解ES6新增字符串扩张方法includes()、startsWith()、endsWith()
2020/05/12 Javascript
[55:25]2018DOTA2亚洲邀请赛3月29日 小组赛A组 VG VS OG
2018/03/30 DOTA
linux系统使用python获取内存使用信息脚本分享
2014/01/15 Python
python中list列表的高级函数
2016/05/17 Python
浅谈python中列表、字符串、字典的常用操作
2017/09/19 Python
python中使用%与.format格式化文本方法解析
2017/12/27 Python
python3爬取各类天气信息
2018/02/24 Python
Python设计模式之组合模式原理与用法实例分析
2019/01/11 Python
基于python3实现倒叙字符串
2020/02/18 Python
Python基于数列实现购物车程序过程详解
2020/06/09 Python
美国厨房和园艺工具网上商店:Nestneed
2019/08/24 全球购物
Linux机考试题
2015/10/16 面试题
经济管理专业毕业生自荐信范文
2014/01/02 职场文书
促销活动策划方案
2014/01/12 职场文书
贸易跟单员英文求职信
2014/04/19 职场文书
小学教师评语大全
2014/04/23 职场文书
临床护理求职信
2014/04/26 职场文书
药剂专业求职信
2014/06/20 职场文书
党的群众路线对照检查材料
2014/08/27 职场文书
群众路线对照检查材料
2014/09/22 职场文书
小学优秀学生评语
2014/12/29 职场文书
vue ref如何获取子组件属性值
2022/03/31 Vue.js
为Centos安装指定版本的Docker
2022/04/01 Servers