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 相关文章推荐
sina的lightbox效果。
Jan 09 Javascript
javascript打开新窗口同时关闭旧窗口
Jan 16 Javascript
js中遍历Map对象的简单实例
Aug 08 Javascript
浅谈js for循环输出i为同一值的问题
Mar 01 Javascript
基于JavaScript实现的折半查找算法示例
Apr 14 Javascript
ionic选择多张图片上传的示例代码
Oct 10 Javascript
浅谈vue中改elementUI默认样式引发的static与assets的区别
Feb 03 Javascript
用vue快速开发app的脚手架工具
Jun 11 Javascript
vue+element 模态框表格形式的可编辑表单实现
Jun 07 Javascript
jQuery表单选择器用法详解
Aug 22 jQuery
vue实现配置全局访问路径头(axios)
Nov 01 Javascript
浅谈小程序globalData的那些事儿
Nov 01 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实现多条件查询实例代码
2010/07/17 PHP
探讨Hessian在PHP中的使用分析
2013/06/13 PHP
php通过array_unshift函数添加多个变量到数组前端的方法
2015/03/18 PHP
php实现源代码加密的方法
2015/07/11 PHP
Yii2框架引用bootstrap中日期插件yii2-date-picker的方法
2016/01/09 PHP
详解PHP中的外观模式facade pattern
2018/02/05 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
2019/12/30 PHP
WebGame《逆转裁判》完整版 代码下载(1月24日更新)
2007/01/29 Javascript
用javascript实现给出的盒子的序列是否可连为一矩型
2007/08/30 Javascript
javascript 限制输入和粘贴(IE,firefox测试通过)
2008/11/14 Javascript
javascript截取字符串(通过substring实现并支持中英文混合)
2013/06/24 Javascript
javaScript面向对象继承方法经典实现
2013/08/20 Javascript
导航跟随滚动条置顶移动示例代码
2013/09/11 Javascript
js实现两个值相加alert出来精确到指定位
2013/09/25 Javascript
javascript里绝对用的上的字符分割函数总结
2014/07/31 Javascript
javascript进行四舍五入方法汇总
2014/12/16 Javascript
jQuery中 prop() attr()使用详解
2015/05/19 Javascript
JavaScript模拟数组合并concat
2016/03/06 Javascript
java中String类型变量的赋值问题介绍
2016/03/23 Javascript
javascript执行环境及作用域详解
2016/05/05 Javascript
实例解析jQuery中proxy()函数的用法
2016/05/24 Javascript
jquery树形菜单效果的简单实例
2016/06/06 Javascript
js实现可输入可选择的select下拉框
2016/12/21 Javascript
vuejs如何配置less
2017/04/25 Javascript
vue实现双向绑定和依赖收集遇到的坑
2018/11/29 Javascript
python显示生日是星期几的方法
2015/05/27 Python
django批量导入xml数据
2016/10/16 Python
python中numpy的矩阵、多维数组的用法
2018/02/05 Python
用Python实现大文本文件切割的方法
2019/01/12 Python
NumPy中的维度Axis详解
2019/11/26 Python
python matplotlib画盒图、子图解决坐标轴标签重叠的问题
2020/01/19 Python
最新版 Windows10上安装Python 3.8.5的步骤详解
2020/11/28 Python
关于抽烟的检讨书
2014/02/25 职场文书
中学生检讨书1000字
2014/10/28 职场文书
天堂的孩子观后感
2015/06/11 职场文书
JavaScript实现显示和隐藏图片
2021/04/29 Javascript