Javascript面向对象编程(三):非构造函数的继承-阿里云开发者社区

开发者社区> 悟静> 正文

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

简介: Javascript面向对象编程(三):非构造函数的继承 ...
+关注继续查看

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

作者: 阮一峰

日期: 2010年5月24日

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

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

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

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

  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库使用的就是这种继承方法。

(完)

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《算法设计编程实验:大学程序设计课程与竞赛训练教材》——导读
全书以知识单元为基本构件,各单元既保持循序渐进的顺序又相对独立,既可拆卸重组、各取所需,又可在此基础上推广或创新,便于各学校按照不同的层次要求组织教学和培训活动。
755 0
django的orm中F对象的使用
今天不巧就用上了。 就是将数据库的字段,自增1的场景。 from django.db.models import F DeployPool.objects.filter(name=deployversion_id).
1150 0
SAS学习笔记之《SAS编程与数据挖掘商业案例》(1)系统简介和编程基础
SAS学习笔记之《SAS编程与数据挖掘商业案例》(1)系统简介和编程基础 1. SAS系统简介 1.1 SAS是先编译后执行的语言,data步标志着编译的开始。 数据指针:当前内存缓存区,输入数据所在位置。 PDV:Program Data Vector,在DATA步中所有涉及的变量被编程当前向量的一部分。 2. SAS编程基础 2.1 SAS逻
1514 0
SAS学习笔记之《SAS编程与数据挖掘商业案例》(3)变量操作、观测值操作、SAS数据集管理
SAS学习笔记之《SAS编程与数据挖掘商业案例》(3)变量操作、观测值操作、SAS数据集管理 1. SAS变量操作的常用语句 ASSIGNMENT 创建或修改变量 SUM 累加变量或表达式 KEEP 规定在数据集中保留的变量 DROP 规定在数据集中删除的变量 ARRAY 定义一个数组 RENAME
1436 0
JavaScript创建对象(四)——组合使用构造函数和原型模式
在JavaScript创建对象(三)——原型模式中,我们阐述了原型模式存在的两个问题:一是没办法通过构造函数初始化对象属性,二是共享引用类型的数据导致数据错乱。
825 0
JavaScript面向对象的编程指南学习笔记
JavaScript面向对象的编程指南学习笔记 第一章 1,用自己的语言描述出,什么是对象、类、封装、聚合、继承、多态? 对象,拥有属性和方法的任何抽象概念。 类,可以实例化,有共同属性或方法(行为)的相似对象,的模板 封装,提供接口,隐藏接口的实现 聚合,将大功能(对象)拆分成小功能(小对象)去实现的逆过程。
8848 0
《JavaScript启示录》——1.4 用户自定义/非原生对象构造函数
关于构造函数比较复杂的一点就是this值在函数内部的使用方式。请记住,构造函数只是一个饼干模具,在将它与new关键字一起使用时,它会创建一个拥有构造函数内部定义的属性和值的对象。在使用new关键字时,this值的字面意思是基于构造函数内部的语句创建的新对象/新实例。
1035 0
SAS学习笔记之《SAS编程与数据挖掘商业案例》(5)SAS宏语言、SQL过程
SAS学习笔记之《SAS编程与数据挖掘商业案例》(5)SAS宏语言、SQL过程 1. 一个SAS程序可能包含一个或几个语言成分: DATA步或PROC步 全程语句 SAS组件语言(SCL) 结构化查询语言(SQL) SAS宏语言 2. 宏触发:% 是一个宏语句或宏函数;&是一个宏变量引用 3. 局部宏变量:一般程序定义的为宏变量。 全局
1705 0
JavaScript 面向对象编程之一
一:Class and private And public JS 中的类以 function 进行声明,同时 JS 也支持声明私有 private 和公有 public 成员,只不过跟 C# 不一样,它们不是使用这两个关键字实现的。
672 0
JavaScript创建对象(二)——构造函数模式
在JavaScript创建对象(一)—— 工厂模式中留下了一个问题,就是创建一个对象怎么判断一个对象的类型。换句话说使用下面这种方式: function createPerson(name, age, job){ var o = new Object(); o.
841 0
+关注
悟静
从事软件行业近二十年
690
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载