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 函数式编程的原理
Oct 16 Javascript
JQuery中$.each 和$(selector).each()的区别详解
Mar 13 Javascript
jquery计算鼠标和指定元素之间距离的方法
Jun 26 Javascript
JavaScript数据类型转换的注意事项
Jul 31 Javascript
bootstrap-datetimepicker实现只显示到日期的方法
Nov 25 Javascript
ES6入门教程之let和const命令详解
May 17 Javascript
easyUI下拉列表点击事件使用方法
May 18 Javascript
深入理解Angularjs中$http.post与$.post
May 19 Javascript
js使用原型对象(prototype)需要注意的地方
Aug 28 Javascript
在vue项目中安装使用Mint-UI的方法
Dec 27 Javascript
5分钟快速掌握JS中var、let和const的异同
Sep 19 Javascript
关于JS模块化的知识点分享
Oct 16 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数组函数序列 之array_count_values() 统计数组中所有值出现的次数函数
2011/10/29 PHP
一个经典的PHP验证码类分享
2014/11/18 PHP
php面向对象中static静态属性和静态方法的调用
2015/02/08 PHP
php实现小程序支付完整版
2018/10/09 PHP
基于laravel-admin 后台 列表标签背景的使用方法
2019/10/03 PHP
js计算字符串长度包含的中文是utf8格式
2013/10/15 Javascript
jquery实现的图片点击滚动效果
2014/04/29 Javascript
浅谈JavaScript Math和Number对象
2015/01/26 Javascript
jquery中的工具使用方法$.isFunction, $.isArray(), $.isWindow()
2015/08/09 Javascript
jQuery实现带动画效果的多级下拉菜单代码
2015/09/08 Javascript
基于JavaScript实现瀑布流布局(二)
2016/01/26 Javascript
js获取当前时间(昨天、今天、明天)
2016/11/23 Javascript
任意Json转成无序列表的方法示例
2016/12/09 Javascript
详解Vue监听数据变化原理
2017/03/08 Javascript
JS+HTML5实现上传图片预览效果完整实例【测试可用】
2017/04/20 Javascript
Bootstrap模态框插入视频的实现代码
2017/06/25 Javascript
jQuery实现简单日期格式化功能示例
2017/09/19 jQuery
JS实现前端缓存的方法
2017/09/21 Javascript
浅谈如何使用 webpack 优化资源
2017/10/20 Javascript
修改Nodejs内置的npm默认配置路径方法
2018/05/13 NodeJs
详解vue指令与$nextTick 操作DOM的不同之处
2018/08/02 Javascript
基于layui实现高级搜索(筛选)功能
2019/07/26 Javascript
详解vite2.0配置学习(typescript版本)
2021/02/25 Javascript
Python中集合类型(set)学习小结
2015/01/28 Python
基于python socketserver框架全面解析
2017/09/21 Python
python单例模式获取IP代理的方法详解
2018/09/13 Python
jupyter修改文件名方式(TensorFlow)
2020/04/21 Python
Python爬虫之Selenium下拉框处理的实现
2020/12/04 Python
端口镜像是怎么实现的
2014/03/25 面试题
考试不及格的检讨书
2014/01/22 职场文书
国旗下演讲稿
2014/05/08 职场文书
材料化学专业求职信
2014/07/15 职场文书
前台接待岗位职责范本
2015/04/03 职场文书
特种设备安全管理制度
2015/08/06 职场文书
python中的class_static的@classmethod的巧妙用法
2021/06/22 Python
Nginx如何配置根据路径转发详解
2022/07/23 Servers