zoukankan      html  css  js  c++  java
  • javascript是怎么继承的

    关于js中的继承,网上有很多文章了,在这里我写出自己对js中的继承的理解。

    第一个阶段:

    function A(){
       
    this.funB = function(){
           alert(
    'A:funB');
       };
    }
    A.prototype 
    = {
       funA:
    function(){
            alert(
    'A:funA');
       }
    };
    function B(){
    }
    function extend(sub,parent){
       sub.prototype 
    = new parent();
       sub.prototype.constructor 
    = sub;
    }
    extend(B,A);
    var b = new B();
    b.funA(); 
    // out 'A:funA'
    b.funB(); // out 'A:funB' 
    alert(b instanceof A); // out "true"

    想必大家一眼就看出什么意思了,先是定义了A,B两个类,然后使用extend方法来让B继承A类。extend的原理就是让父类 new 到子类的prototype上。

    用instanceof来检测也为true,想要让instanceof为true,那就必须两个类的prototype对象要为同一个object,不管是间接或直接的。

    这样的方式有没有问题呢?在通常面向对象语言中,子类在继承父类时,是不会触发父类的构造函数执行,而这里是父类是在继承时执行的。

    第二个阶段

    function A(){
       
    this.Astr = 'hello A';
    }
    A.prototype 
    = {
       funA:
    function(){
          alert(
    this.Astr);
       }
    };
    function B(){
       arguments.callee.superclass 
    && arguments.callee.superclass.apply(this,arguments);
       
    this.Bstr = 'hello B';
    }
    B.prototype 
    = {
       funB:
    function(){
          alert(
    this.Bstr);
       }
    };
    function C(){
       arguments.callee.superclass 
    && arguments.callee.superclass.apply(this,arguments);
       alert(
    this.Astr);
       alert(
    this.Bstr);
    }
    function extend(sub,parent){
        
    var subproto = sub.prototype;
        sub.prototype 
    = parent.prototype;
        
    typeof subproto != 'object' && (subproto = {});
        
    typeof sub.prototype != 'object' && (sub.prototype = {});
        
    for(var i in subproto){
           sub.prototype[i] 
    = subproto[i];
        }
        sub.superclass 
    = parent;
    }
    //B 继承 A
    extend(B,A);
    //C 继承 B
    extend(C,B);
    var c = new C(); // out 'hello A','hello B'
    c.funA(); //out 'hello A'
    c.funB(); // out 'hello B'
    alert(c instanceof A) // out true
    alert(c instanceof B) // out true;

     这里对extend方法做了一些改动,这里有个约定,每个子类都拥有一个superclass的属性,用来引用她所继承的父类,用一个空函数proto来获得父类的prototype,实例化给子类的prototype,这样就没有执行父类构造器。

    而是在子类的构造器中用下来一段代码来执行约定要的父类构造器。

    arguments.callee.superclass && arguments.callee.superclass.apply(this,argumengs);

    这样就完成了类的继承。

    对于上面的代码有没有更方便的继承写法呢,修改Function的原型来看看:

    Function.prototype.extend = function(parent){
        
    var subproto = this.prototype;
        
    this.prototype = parent.prototype;
        
    typeof subproto != 'object' && (subproto = {});
        
    typeof this.prototype != 'object' && (this.prototype = {});
        
    for(var i in subproto){
           
    this.prototype[i] = subproto[i];
        }
        
    this.superclass = parent;
        
    return this;
    }
    function A(){
       
    this.Astr = 'hello A';
    }
    A.prototype 
    = {
       funA:
    function(){
          alert(
    this.Astr);
       }
    };
    var B = function(){
       arguments.callee.superclass 
    && arguments.callee.superclass.apply(this,arguments);
       
    this.Bstr = 'hello B';
    }
    B.prototype 
    = {
       funB:
    function(){
          alert(
    this.Astr);
       }
    };
    B.extend(A);
    var C = function(){
       arguments.callee.superclass 
    && arguments.callee.superclass.apply(this,arguments);
       alert(
    this.Astr);
       alert(
    this.Bstr);
    }.extend(B);


    var c = new C(); // out 'hello A','hello B'
    c.funA(); //out 'hello A'
    c.funB(); // out 'hello B'
    alert(c instanceof A) // out true
    alert(c instanceof B) // out true;

     这里的extend做的事情是: subproto引用子类的原prototype ,将子类的prototype 指向 父类的prototype对象,这样就继承了父类(这样的目的是让 子类实例 instanceof 父类 为 true)。然后历遍subproto,将原prototype的成员添加到现prototype上,这样子类重名的重名的成员就会覆盖父类的成员。最后将子类的属性superclass 指向 父类。

    js继承的关键就是保持原型链的唯一性,instanceof就以判断实例的__proto__是否和父类的prototype为同一Object.

    今天就写这样多,天黑了,下班咯

  • 相关阅读:
    HAProxy、Keepalived 在 Ocatvia 的应用实现与分析
    Octavia 的 HTTPS 与自建、签发 CA 证书
    Octavia 创建 loadbalancer 的实现与分析
    OpenStack Rally 质量评估与自动化测试利器
    自建 CA 中心并签发 CA 证书
    Failed building wheel for netifaces
    通过 vSphere WS API 获取 vCenter Datastore Provisioned Space 置备空间
    OpenStack Placement Project
    我们建了一个 Golang 硬核技术交流群(内含视频福利)
    没有图形界面的软件有什么用?
  • 原文地址:https://www.cnblogs.com/xingzhi/p/2155040.html
Copyright © 2011-2022 走看看