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 定义初始化数组函数
Sep 07 Javascript
javascript 学习笔记(八)javascript对象
Apr 12 Javascript
纯javascript实现分页(两种方法)
Aug 26 Javascript
Angular JS数据的双向绑定详解及实例
Dec 31 Javascript
js获取浏览器的各种属性
Apr 27 Javascript
JS实现求数组起始项到终止项之和的方法【基于数组扩展函数】
Jun 13 Javascript
详解在WebStorm中添加Vue.js单文件组件的高亮及语法支持
Oct 21 Javascript
canvas+gif.js打造自己的数字雨头像的示例代码
Oct 26 Javascript
node.js用fs.rename强制重命名或移动文件夹的方法
Dec 27 Javascript
vue中使用cropperjs的方法
Mar 01 Javascript
快速对接payjq的个人微信支付接口过程解析
Aug 15 Javascript
微信小程序实现手指拖动选项排序
Apr 22 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
JavaScript实现删除电脑的关机键
2016/07/26 PHP
PHP读取大文件的几种方法介绍
2016/10/27 PHP
php curl获取https页面内容,不直接输出返回结果的设置方法
2019/01/15 PHP
JavaScript版代码高亮
2006/06/26 Javascript
JavaScript 事件对象的实现
2009/07/13 Javascript
javascript cookie操作类的实现代码小结附使用方法
2010/06/02 Javascript
javascript基本类型详解
2014/11/28 Javascript
jQuery中data()方法用法实例
2014/12/27 Javascript
使用vue.js开发时一些注意事项
2016/04/27 Javascript
JavaScript mixin实现多继承的方法详解
2017/03/30 Javascript
微信小程序 实例开发总结
2017/04/26 Javascript
JavaScript字符串检索字符的方法
2017/06/23 Javascript
当vue路由变化时,改变导航栏的样式方法
2018/08/22 Javascript
JS 验证码功能的三种实现方式
2018/11/26 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
Vue源码分析之Vue实例初始化详解
2019/08/25 Javascript
node实现mock-plugin中间件的方法
2019/12/25 Javascript
小程序中手机号识别的示例
2020/12/14 Javascript
Python中关键字is与==的区别简述
2014/07/31 Python
在Python的循环体中使用else语句的方法
2015/03/30 Python
浅谈numpy库的常用基本操作方法
2018/01/09 Python
numpy使用技巧之数组过滤实例代码
2018/02/03 Python
对python cv2批量灰度图片并保存的实例讲解
2018/11/09 Python
python找出一个列表中相同元素的多个索引实例
2019/06/11 Python
使用python绘制cdf的多种实现方法
2020/02/25 Python
详解Python直接赋值,深拷贝和浅拷贝
2020/07/09 Python
python利用opencv保存、播放视频
2020/11/02 Python
HTML5中原生的右键菜单创建方法
2016/06/28 HTML / CSS
爱尔兰灯和灯具网上商店:Lights.ie
2018/03/26 全球购物
Dillard’s百货官网:Dillards.com
2018/05/26 全球购物
管理心得体会
2013/12/28 职场文书
给面试官的感谢信
2014/02/01 职场文书
寄语是什么意思
2014/04/10 职场文书
党员一帮一活动总结
2014/07/08 职场文书
建筑学专业自荐书
2014/07/09 职场文书
Java实现经典游戏泡泡堂的示例代码
2022/04/04 Java/Android