这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承"。

今天是最后一个部分,介绍不使用构造函数实现"继承"。

一、什么是"非构造函数"的继承?

比如,现在有一个对象,叫做"中国人"。

  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之非构造函数的继承的更多相关文章

  1. (三)Javascript面向对象编程:非构造函数的继承

    Javascript面向对象编程:非构造函数的继承   这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使 ...

  2. Javascript面向对象编程(三):非构造函数的继承(对象的深拷贝与浅拷贝)

    Javascript面向对象编程(三):非构造函数的继承   作者: 阮一峰 日期: 2010年5月24日 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现&quo ...

  3. javascript面向对象(三):非构造函数的继承

    本文来自阮一峰 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使用构造函数实现"继承" ...

  4. Javascript面向对象编程(三) --- 非构造函数的继承

    一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese = { nation:'中国' }; 还有一个对象,叫做&qu ...

  5. 转载:javascript面向对象编程:非构造函数的继承

    一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese = { nation:'中国' }; 还有一个对象,叫做&qu ...

  6. Javascript面向对象编程(三):非构造函数的继承 by 阮一峰

    今天是最后一个部分,介绍不使用构造函数实现"继承". 一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Ch ...

  7. (转)Javascript面向对象编程(三):非构造函数的继承(作者:阮一峰)

    不使用构造函数实现"继承". 一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Chinese = { na ...

  8. Javascript面向对象编程(三):非构造函数的继承

    转载自:http://www.ruanyifeng.com/blog/2010/05/object-oriented_javascript_inheritance_continued.html 一.什 ...

  9. Javascript面向对象编程:非构造函数的继承

    今天是最后一个部分,介绍不使用构造函数实现"继承". 一.什么是"非构造函数"的继承? 比如,现在有一个对象,叫做"中国人". var Ch ...

随机推荐

  1. linux基础命令---whereis

    whereis 查找命令的位置,包括执行文件.源代码.手册文件. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法       ...

  2. Linux基础命令---e2fsck

    ex2fsck 检查ext2.ext3.ext4文件系统,如果系统已经挂载了,那么不建议去检查,因为这样是不安全的.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.op ...

  3. SpringBoot之集成WebSocket

    websocket是什么不做介绍.开发环境:jdk1.8,win7_64旗舰版,idea   1.初始化一个springboot项目   2.加入websocket依赖 <!-- springb ...

  4. Ubuntu系统下Jenkins的git构建基本方法

    上一博文讲到了本地脚本的构建方法. 本篇博文主要讲“Ubuntu系统下Jenkins的git构建基本方法”. 点击保存后即可完成简单的构建. 构建触发器 这个触发器是决定什么时候触发构建,可以设置为定 ...

  5. (三)github之GIT的导入

    什么是版本管理? git是一款[分散型版本管理]软件,提供了开发过程中不可少的功能,例如记录一款软件添加或者更改源代码的过程,回溯到特定阶段,恢复误删除的文件等. 集中型:将仓库集中放在服务器中,一旦 ...

  6. Idea中Maven仓库配置会自动恢复

    手头有好几个项目,关闭一个项目,打开另一个项目,发现又在重新下载jar包,打开设置一看,maven配置又恢复到了.m2下边.idea配置的maven会自动恢复吗? 答案是否定的,idea的设置有两个, ...

  7. Python3.x(windows系统)安装libxml2库

    Python3.x(windows系统)安装libxml2库 cmd安装命令: pip install lxml 执行结果: 再执行命令: pip install virtualenv 执行结果:

  8. Android 基础知识点(一)

  9. 20145205 武钰 《网络对抗》Exp8 Web基础

    一点题外话 本次实验我三号完成的,由于一些原因吧,一直没发博客,拖到了现在,这里说就是评判一下自己的懒惰. 实验后问题回答 (1)什么是表单 表单在网页中主要负责数据采集功能. 一个表单有三个基本组成 ...

  10. 小工具:word表格文字转化成insert语句

    群里的一个朋友有个需要,要让把word里的表格数据插入到数据库里面. 我的思路是,把格式化的数据转成insert语句,然后去执行就可以了. 要求的insert语句格式是:'insert into xx ...