资讯专栏INFORMATION COLUMN

面向对象-非构造函数的继承

zhangke3016 / 2105人阅读

摘要:这两个都是用字面量方法创建的普通对象,不是构造函数无法使用构造函数的原型链继承的方法的实现继承。

1.最近一直再看javascript高级程序设计3,面向对象章节,前面写了两篇读书笔记

(1)构造函数 --创建对象
(2)构造函数的原型链继承
现在又在网上看到阮一峰大大的一篇非构造函数继承的文章,特意借来学习一下!

非构造函数继承--阮一峰

一:什么是非构造函数的继承?
    比如:一个对象叫做中国人
        一个对象叫做医生
var Chinese = {
    nation:"中国"
}
var doctor = {
    career:"医生"
}

怎样才能让“医生”去继承“中国人”,也就是说,我怎样才能生成一个“中国医生”的对象?
这里注意。这两个都是用字面量方法创建的普通对象,不是构造函数无法使用构造函数的原型链继承的方法的实现继承。

第一种:object方法

json格式发明人提出的一种方法
function object(o){
    function F(){};    // 创建一个空构造函数
    F.prototype = o;   // 原型对象指向父对象
    return new F();
}

这个object函数的作用就是将子对象的prototype属性指向父对象,从而使的父子对象连在一起

(1)使用时先在父对象基础声称子对象

 var Doctor = object(Chinese);

(2)然后给自对象赋上自己的属性

 var Doctor.carrer = "医生";

(3)这样子对象就继承了父对象的属性了

 alert(Doctor.nation);  // "医生"

第二种:浅拷贝

除了使用“prototype”链以外,还有另一种思路:就是把父对象的属性,全部拷贝给子对象,也能实现继承。
下面这个函数,就是在做拷贝:
function extendCoby(p){
    var c = {};
    for(var i in p){
        c[i] = p[i];
    }
    c.uber = p; // 软大大:uber是一个德语词,意思是"向上"、"上一层"
    return c;
}
使用的时候,这样写
var Doctor = extend(Chinese);
Doctor.carrer = "医生";
alert(Doctor.nation);  // 中国

但是这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正的拷贝,因此存在父对象被篡改的可能。

请看现在给Chinese添加一个出生地属性,它的值是一个数组。

Chinese.birthPlace = ["北京","上海","香港"];

通过extendCopy()函数,Docttor继承了Chinese

var Doctor = extendCopy(Chinese);

然后我们为出生地添加一个城市:

Doctor.birthPlace.push("厦门");

此时,发生了什么事?

alert(Doctor.birthPlace);   // 北京,上海,香港,厦门
alert(Chinese.birthPlace); //  北京,上海,香港,厦门

所以,extendCopy()只是拷贝基本数据类型,我们把这种拷贝叫做浅拷贝。
这是早期的jquery实现继承的方式

第三种 深拷贝

所谓深拷贝,就是能够真正意义上的数组和对象的拷贝。
它的实现并不难,只要递归调用浅拷贝就可以啦
function deepCopy(p,c){ //参数p,c顺序万不可写反,因为第一次c为空
    var c = c || {};   // 第一次执行函数的时候 c为 空对象
    for(var i in p){
        if(typeof p[i] === "object"){ // 判断对象p的一个属性值是否为复杂数据类型object或array
            // [] 或 {} 判断
            c[i] = (p[i].constructor === Array) ? [] : {};
            deepCopy(p[i],c[i]);         // 递归调用此方法
        }else{
            c[i] = p[i];                //简单数据类型直接赋值
        }
    }
    return c;                          // 将新对象c返回出来
}
var Chinese = {
    nation:"中国",
    place:["A","B","C"],
    say:function(){
        alert(this.nation);
    }
}
var Doctor = deepCopy(Chinese); // 调用deepCopy创建新对象
Doctor.carrer = "医生";
Doctor.place.push("X");
console.log(Doctor);
console.log(Chinese);

此方法是目前jq实现集成的方法

感悟:个人感觉此方法只适用简单方法,不适合复杂对象,复杂对象还是得靠构造函数原型链的继承!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81180.html

相关文章

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

    摘要:原文链接一什么是非构造函数的继承比如,现在有一个对象,叫做中国人。通过函数,继承了。中国北京上海香港厦门北京上海香港厦门北京上海香港这时,父对象就不会受到影响了。目前,库使用的就是这种继承方法。 原文链接 一、什么是非构造函数的继承? 比如,现在有一个对象,叫做中国人。 var Chinese = { nation: 中国 } 还有一个对象,叫做医生。 var Doctor = {...

    jaysun 评论0 收藏0
  • JS对象(1)重新认识面向对象

    摘要:对象重新认识面向对象面向对象从设计模式上看,对象是计算机抽象现实世界的一种方式。除了字面式声明方式之外,允许通过构造器创建对象。每个构造器实际上是一个函数对象该函数对象含有一个属性用于实现基于原型的继承和共享属性。 title: JS对象(1)重新认识面向对象 date: 2016-10-05 tags: JavaScript 0x00 面向对象 从设计模式上看,对象是...

    superw 评论0 收藏0
  • PHP面向对象

    摘要:面向对象面向对象基础面向对象什么是类具有相同属性特征和方法行为的一系列个体的集合,类是一个抽象的概念。析构函数,当一个对象被销毁前,自动调用。作用是为新克隆的对象进行初始化赋值对象序列化时,自动调用。使用抽象类的作用限制实例化。 面向对象 面向对象基础 面向对象 什么是类? 具有相同属性(特征)和方法(行为)的一系列个体的集合,类是一个抽象的概念。 什么是对象? 从类中,拿到的具有具体...

    seanlook 评论0 收藏0
  • 面向对象 JavaScript

    摘要:是完全的面向对象语言,它们通过类的形式组织函数和变量,使之不能脱离对象存在。而在基于原型的面向对象方式中,对象则是依靠构造器利用原型构造出来的。 JavaScript 函数式脚本语言特性以及其看似随意的编写风格,导致长期以来人们对这一门语言的误解,即认为 JavaScript 不是一门面向对象的语言,或者只是部分具备一些面向对象的特征。本文将回归面向对象本意,从对语言感悟的角度阐述为什...

    novo 评论0 收藏0
  • 浅谈JavaScript面向对象和它封装、继承、多态

    摘要:会造成内存浪费的问题构造函数继承声明父类声明子类生成实例组合式继承组合式继承是汲取了两者的优点,既避免了内存浪费,又使得每个实例化的子类互不影响。 写在前面 既然是浅谈,就不会从原理上深度分析,只是帮助我们更好地理解... 面向对象与面向过程 面向对象和面向过程是两种不同的编程思想,刚开始接触编程的时候,我们大都是从面向过程起步的,毕竟像我一样,大家接触的第一门计算机语言大概率都是C语...

    MAX_zuo 评论0 收藏0

发表评论

0条评论

zhangke3016

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<