• JS的继承


    对于继承的实际运用还没有很好的理解,这里就先说说JS中继承的实现。

    类式继承

    作为基于原型的语言,JS也可以模仿类式继承。首先声明一个父类

    function Person(name, age) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.sayHello = function() {
        console.log("hello");
    };

    继承就显得复杂一点

    function Programmer(name, age, work) {
        Person.apply(this, arguments);    //修正父类构造函数的this
        this.work = work;
    }
    Programmer.prototype = new Person();
    Programmer.prototype.constructor = Programmer;
    Programmer.prototype.program = function() {
        console.log("coding");
    };

    var p = new Programmer("jay", 26, "javascript");
    p.sayHello(); //hello
    console.log(p.name); //jay 注意这个不是继承属性,而是p本身的属性哦

    把Programmer.prototype指向父类Person的一个实例对象,那么在子类Programmer的实例中访问成员时,如果找不到,就会去这个Person实例对象里找,还没有就到Person.prototype里找,相当于人为的设置了一条原型链来达到继承的效果。

    只要不把Programmer.prototype重写,Programmer的所有实例的原型对象共享同一个对象,即Person实例。我们仍然可以通过修改原型来达到修改所有实例的效果。

    有时父类的构造函数很庞大,里面有很多复杂的或我们不需要的操作,我们想要避免创建父类的实例,改进的方法是借用一个空的构造函数作为中间量来链接原型链,我们把整个过程包装到一个函数里

    function inherit(subClass, superClass) {
        var F = function() {};
        F.prototype = superClass.prototype;
        subClass.prototype = new F();
        subClass.prototype.constructor = subClass;
    subClass.superproto = superClass.prototype; //增加一个自定义属性superproto,这样我们可以通过这个属性引用到父类构造函数 }
    function Programmer(name, age, work) {
        Programmer.superproto.constructor.apply(this, arguments);    //等价于Person.apply(this, arguments),这样就避免了在子类的声明中固化父类构造函数名称
        this.work = work;
    }
    inherit(Programmer, Person);
    Programmer.prototype.program = function() {
        console.log("coding");
    };

    注意到,作为一个中间量,我们可以只创建一个F然后重用它,因此inherit可以这样改进一下

    var inherit = (function() {
        var F = function() {};
        return function(subClass, superClass) {
            F.prototype = superClass.prototype;
            subClass.prototype = new F();
            subClass.prototype.constructor = subClass;
            subClass.superproto = superClass.prototype;
        };
    })();

    掺元类(Mixin)

    这是一种代码重用的方法而不是严格的继承。其做法大体是,先创建一个包含各种公用方法的类,即掺元类,然后用它去扩充其它类。掺元类一般不会实例化也不直接调用,其目的就是扩充其它类,提供自己的方法。

    function augment(destClass, srcClass) {
        for (method in srcClass.prototype) {
            if (!destClass.prototype[method]) {
                destClass.prototype[method] = srcClass.prototype[method];
            }
        }
    }

    扩充多个掺元类,变相的多继承

    function augment(destClass /*, a number of srcClasses */) {
        var classes = Array.prototype.splice.call(arguments, 1);
        for (var i = 0, len = classes.length; i < len; i++) {
            var srcClass = classes[i];
            for (method in srcClass.prototype) {
                if (!destClass.prototype[method]) {
                    destClass.prototype[method] = srcClass.prototype[method];
                }
            }
        }
    }

    参考:http://blog.csdn.net/pigpigpig4587/article/details/25152031

    http://www.cnblogs.com/snandy/archive/2013/05/24/3086663.html

  • 相关阅读:
    R语言 逐步回归分析
    R语言 一元线性回归
    基于Qt的信号分析简单应用软件的设计
    【图论 5】图的应用——拓扑排序和关键路径
    【图论 3】图的应用——最小生成树
    B+树
    大概是最简明的B树博客了
    KMP算法
    【内存管理篇】基本分页存储管理方式
    双向链表为何时间复杂度为O(1)?
  • 原文地址:https://www.cnblogs.com/coiorz/p/4740269.html
Copyright © 2020-2023  润新知