继承对象【javascript继承】之——原型链继承和类式继承

本文纯属个人见解,是对前面学习的总结,如有描述不正确的地方还请高手指正~

    什么是继承啊?答:别人白给你的程过就叫继承。

    为什么要用继承呢?答:捡现成的呗。

    好吧,既然大家都想捡现成的,那就要学会怎么继承!

    在懂得之前,你要需先懂得构造数函对象原型链等观点......

    JS里用常的两种继承方法

    

  1. 原型链继承(对象间的继承)
  2. 类式继承(构造数函间的继承)

    原型链继承

//要继承的对象
var parent={
      name : "baba"
    say : function(){
                   alert("I am baba");
            }
}

//新对象
var child = proInherit(parent);

//测试
alert(child.name);  //"baba"
child.say();        //"I am baba"
利用proInherit(obj)法方,传入对象,能就实现对象的属性及法方的继承,这个法方不是置内法方,所以要自己义定,非常单简:
function proInherit(obj){
       function F () {}
       F.prototype = obj;
       return new F();
}
其中F()为一个临时的空的构造数函,然后将F()的原型置设为父对象,但是同时它又通过受益于_proto_接链而有具其父亲对象的全体功能。

    链式图解:

         继承和对象

 

    类式继承

//类父构造数函
function Parent() {
        this.name = "baba";
}
//类父原型法方
Parent.prototype.getName = function () {
        return this.name;
}

//类子构造数函
function Child() {
       this.name = "cc";
}

//类式继承
classInherit(Parent, Child);

//实例
var child = new Child();
alert(child.getName())     //“baba”
上面我们来看看这个继承的症结法方:classInherit(Parent,Child)
    每日一道理
巴尔扎克说过“不幸,是天才的进升阶梯,信徒的洗礼之水,弱者的无底深渊”。风雨过后,眼前会是鸥翔鱼游的天水一色;走出荆棘,前面就是铺满鲜花的康庄大道;登上山顶,脚下便是积翠如云的空蒙山色。 在这个世界上,一星陨落,黯淡不了星空灿烂,一花凋零,荒芜不了整个春天。人生要尽全力度过每一关,不管遇到什么困难不可轻言放弃。
var classInherit = (function () {
      var F = function () { }
      return function (P, C) {
              F.prototype = P.prototype;
              C.prototype = new F();
              C.prototype.constructor = C;
      }
}());
 分析一下这个法方:

    

  1. 首先创立一个空的构造数函F(),用其实例的_proto_属性来构建类父与类子的原型链。起到一个代理的作用,目标是为了防止C.prototype = P.prototype,这样会在类子实例化后修改属性或法方时候,连同类父一同修改。
  2. 团体用采即时数函并且在包闭中存储F(),防止多次继承时候创立量大的空的构造数函,从而少减消费内存。
  3. 最后一行的意思是,由于原型链的关系,C的实例对象的constructor会向指P,所以新重置设。

    链式图解:

            继承和对象

    种这方法虽然在实例的时候继承了原型法方,但是类父的属性没法继承,上面绍介一种复制继承,算是对类式继承的充补。

    复制继承:

//复制继承
function copyInherit(p, c) {
     var i,
          toStr = Object.prototype.toString,
          astr = "[object Array]";
     c = c || {}; 
     for (i in p) {
         if (p.hasOwnProperty(i)) {
            if (typeof p[i] === "object") {
                 c[i] = toStr.call(p[i]) == astr ? [] : {};
                 c[i] = copy(p[i], c[i]);
             }
             else {
                 c[i] = p[i];
             }
          }
      }
      return c;
}

//写重Parent
function Parent() {
      this.name = "pp";
      this.obj= {a:1,b:2};
      this.arr= [1, 2]
}
//实例
var child = new Child();
var parent = new Parent();
copyInherit(parent, child);
alert(child.name)    //"baba"
alert(child.arr)     //1,2
alert(child.obj.a)   //1
 分析下copyInherit(p,c)

    当一个值予赋一个变量时候,分为传值和传引用两种方法,当你父对象内属性含包数组类型或是对象类型时候,  c[i] = toStr.call(p[i]) == astr ? [] : {};这一句会防止修改子对象属性而起引的父对象属性被改动。

    总结:

    类式继承较比泛广,因为大家都较比熟习种这构造数函方法,但是内存占用较比大。而原型式继承,占用内存较比小,但是含包数组,或者对象类型的克隆较比费事。复制继承单简,而且用应泛广。

 

 

 

 

 

文章结束给大家分享下程序员的一些笑话语录: 神灯新篇
一个程序员在海滩上发现了一盏神灯。他在灯上擦了几下,一个妖怪就从灯里跳出来说:“我是世界上法术最强的妖怪。我可以实现你的任何梦想,但现在,我只能满足你一个愿望。”程序员摊开了一幅中东地图说:“我想让中东得到永久的和平。”妖怪答道:“哦,我没办法。自打创世纪以来,那里的战火就没有停息过。这世上几乎没有我办不到的事,但这件事除外。”程序员于是说:“好吧,我是一个程序员,为许多用户编写过程序。你能让他们把需求表述得更清楚些,并且让我们的软件项目有那么一两次按进度按成本完成吗?”妖怪说:“唔,我们还是来看中东地图吧。”


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值