zoukankan      html  css  js  c++  java
  • 《JavaScript高级程序设计》笔记——关于继承

         继承在JavaScript中是一种“奇葩”的存在,因为其本身并没有类(class)的概念(ES5),所以只能用其他方式(原型链、构造函数、对象实例)来模拟继承的行为。既然是模拟,那就应该是想办法实现继承的行为特点,个人认为继承的核心就是:能复用就复用,不能复用的就复制

         写在前面:
      方法是属性的特殊形式,这里就用属性全权代表。
         函数构造器里的属性是实例属性,每个实例都有自己的一份,实例之间互不影响。
         原型对象里的属性为每个实例共享,一旦改变,所有实例的原型属性都改变。
      以下的父类(SuperType)和子类(SubType)都有自己的实例属性和原型属性,各自的构造函数就不重复了,只列出继承核心步骤以突出重点。

         1.原型链继承:
         
    1 SubType.prototype = new SuperType();
         特点:父类的所有属性(包括实例属性和原型属性)都作为了子类的原型属性。
         说明:纳尼?!一下都弄到原型属性里这样合适么,你考虑过实例属性的感受么?在父级既然是每个实例独享一份,到了子类却变成共享的了,这样使用限制很大哟!
     
         2.借用构造函数继承:
         克服原型链的不足:实例属性用构造器继承。
     
    1 function SubType(){
    2   SuperType.call(this);
    3 }
         特点:父类的实例属性在子类还是实例属性,每个实例独一份互不干扰;另外,还可以利用call方法的特性给父类的构造函数传递参数。
         说明:原型链的问题克服了,复用呢?父类的原型属性根本就没有在子类中体现啊!这样也没法用呢。
     
         3.组合继承:
         综合一下前两种继承的优点吧,上帝的归上帝,凯撒的归凯撒。
     
    function SubType(){
        //继承实例属性
        SuperType.call(this);
    }
    //继承原型属性
    SubType.prototype = new SuperType();
         特点:这样比较完美了,父类的实例属性在子类中单独继承,原型属性也有了复用的特点;并且保留了传参数的优点。
         说明:但是处女座的朋友会发现,这关键的两步都调用了父类的构造函数,直接结果就是子类继承父类的实例属性会存在两份,一份在子类的原型对象中,一份在子类实例中,只不过原型属性被实例属性覆盖罢了。这是多么可耻的浪费啊!
     
         4.寄生组合式继承:
         请先不要问我“寄生”是什么意思~~组合继承的“浪费”主要是在原型链继承的过程中发生的,所以我们现在不借助父级实例重写子类原型对象,单独给子类一个只包括父类原型对象属性的对象即可。
         首先来个用于复制父类原型对象的工具函数:    
        
     1 function copy(uber){//工具函数  
     2   var F = function(){};
     3   F.prototype = uber;
     4   return new F();
     5 }
     6 //继承实例属性
     7 function SubType(){
     8   SuperType.call(this);  
     9 }
    10 //继承原型属性
    11 SubType.prototype = copy(SubType.prototype);        
    12 SubType.prototype.constructor = SubType;  //不要忘记修正constructor   
         特点:完美实现了继承,而且没有浪费内存空间,还能传参;就是写起来有点儿麻烦
     
         5.原型式继承
         好吧回过头来说一下这个寄生,在讲寄生前允许我啰嗦一下“原型式继承”:
         
    1 function copy(obj){  
    2     var F = function(){};
    3     F.prototype = obj;
    4     return new F();
    5 }
         特点:这种继承基于实例,只需给一个父类的实例对象就“还”一个子类实例对象,直接绕过构造函数,很简单吧。
         说明:与其说是继承,其实这种方式更像是一种对象的“浅复制”,而且还有两个缺陷:1.不同子对象之间根本就没有函数的复用,2.由于是浅复制不同子对象之间会共用引用类型的属性,不能随意改动。但作者尼古拉斯说是,那就是吧。
         
         6.寄生式继承
         寄生式继承是对原型式继承的一种加强:
     
    1 function createAnother(original){
    2     var clone = object(original);     //不一定必须用object方法,基于original复制新创建的即可
    3     clone.sayHi = funciton(){  ……   }     // 增强
    4     return clone;
    5 }
         特点:这里返回的clone不仅有original的所有属性,还有自己的方法。
         说明:寄生组合式继承的两个缺陷没有修复,所以我觉得这个继承方式依然很牵强;个人感觉“寄生”的由来就是将自己sayHi放在了original上面,额……回到第四种继承方式,我想体现寄生的地方就在于SubType.prototype.constructor = SubType(个人观点)
     
         总结:最常用的继承方式应该是组合式继承  和  寄生组合式继承
         
         以上是基于JS红宝书6.3继承章节的一些读书心得,欢迎吐槽。
     
     
  • 相关阅读:
    常用Linux基础命令
    makefile基础
    获得当前的时间——system.currentTimeMillis()
    MapReduce提供的输入输出格式
    Hadoop HDFS文件操作的Java代码
    Hadoop2.2.0完全分布式配置
    Hadoop2.2.0伪分布模式配置
    Eclipse Plugin for Hadoop2.2.0
    Hadoop2.2.0单机模式配置
    Asp.Net 禁用cookie后使用session
  • 原文地址:https://www.cnblogs.com/mengda1027/p/4526767.html
Copyright © 2011-2022 走看看