• jquery、prototype、mootools、YUI的继承的实现


    铺垫:js是基于原型的语言,其继承和传统的java式的继承有区别,实现js的继承除了要实现类本身方法的继承(实际上是从父类拷贝的),还要将原型继承(from原型链)。js框架对这种继承有着不同深度的封装,看下在这4个框架中的继承是如何实现的。实现这样一个场景,一个Window 类,Window类派生出一个Dialog,Dialog和Window有相同的构造方法,有不同的类型名称,他们均包含getType和 getConstructor两个方法。

    原生:

    //Window
    var Window = function(){
        this.init.apply(this,arguments);
    };
    Window.prototype = {
        init:function(name){
            this.type = this.getConstructor();
            this.name = name
        },
        getType:function(){
            return this.type;
        },
        getConstructor:function(){
            return ‘Window’;
        }
    
    };
    //Dialog
    var Dialog = function(){
        Window.apply(this,arguments);//继承构造器
    };
    Dialog.prototype = new Window();//继承原型
    Dialog.prototype.getConstructor = function(){//扩展父类方法
        return ‘Dialog’;
    };
    var _window = new Window(‘box1′);
    var _dialog= new Dialog(‘box2′);
    console.log(_window.getType === _dialog.getType);//true
    

    这是原生的继承的实现,可以看到继承的过程有三部分,继承构造器,继承原型,扩展。

    jquery:

    //Window
    var Window = function(){
        this.init.apply(this,arguments);
    };
    Window.prototype = {
        init:function(name){
            this.type = this.getConstructor();
            this.name = name
        },
        getType:function(){
            return this.type;
        },
        getConstructor:function(){
            return ‘Window’;
        }
    };
    //Dialog
    var Dialog = function(){
        Window.apply(this,arguments);
    };
    jQuery.extend(Dialog.prototype,Window.prototype,{
        getConstructor:function(){
            return ‘Dialog’;
        }
    });
    var _window = new Window(‘box1′);
    var _dialog= new Dialog(‘box2′);
    console.log(_window.getType === _dialog.getType);
    

    jquery的extend比较简单,只是简单的扩充,并不是真正的继承,因此实现代码比较冗余。

    prototype:

    //Window
    var Window = Class.create({
        initialize:function(){
            this.type = this.getConstructor();
            this.name = name;
        },
        getType:function(){
            return this.type;
        },
        getConstructor:function(){
            return ‘Window’;
        }
    });
    //Dialog
    var Dialog = Class.create(Window,{
        getConstructor:function(){
            return ‘Dialog’;
        }
    });
    var _window = new Window(‘box1′);
    var _dialog= new Dialog(‘box2′);
    console.log(_window.getType === _dialog.getType);//true
    

    prototype 的继承很简洁,也很语义,只是这个Class以prototype的方式进行了一次封装,在定义class的时候必须指定initialize(构造器),其他的方法默认都挂载在prototype上。但若要增加Class本身的方法,就需要使用Class.pro = sth,且这个属性是无法直接继承的。

    mootools:

    //Window
    var Window = new Class({
        initialize:function(name){
            this.type = this.getConstructor();
            this.name = name;
        },
        getType:function(){
            return this.type;
        },
        getConstructor:function(){
            return ‘Window’;
        }
    });
    //Dialog
    var Dialog = new Class({
        Extends:Window,
        getConstructor:function(){
            return ‘Dialog’;
        }
    });
    var _window = new Window(‘box1′);
    var _dialog= new Dialog(‘box2′);
    console.log(_window.getType === _dialog.getType);
    

    mootools的实现思路和prototype大同小异,优点是简洁语义,缺点是缺少灵活性,理由同prototype。

    YUI3

    //Window
    var Window = function(){
        this.init.apply(this,arguments);
    };
    Window.prototype = {
        init:function(name){
            this.type = this.getConstructor();
            this.name = name
        },
        getType:function(){
            return this.type;
        },
        getConstructor:function(){
            return ‘Window’;
        }
    
    };
    //Dialog
    var Dialog = function(){
        this.constructor.superclass.constructor.apply(this, arguments);
        this.init.apply(this,arguments);
    };
    Y.extend(Dialog,Window,{
        getConstructor:function(){
            return ‘Dialog’;
        }
    });
    var _window = new Window(‘box1′);
    var _dialog = new Dialog(‘box2′);
    console.log(_window.getType === _dialog.getType);
    

    实际上Y.extend是由Y.mix配置来的,因此,Y.extend既可以从原型链上继承,也可以从类本身的方法和属性继承,个人感觉是比较灵活的一种实现,但在写代码的时候则需要手写一句this.constructor.superclass.constructor.apply(this, arguments)来实现构造器的继承,所以代码不够简洁和直观。

    其他框架比如Ext和Dojo的实现基本上是prototype的翻版,只是将Class的定义从Class.create改成了declare。

    总上所述,比较这四种js框架在继承方面的优劣:

    • jquery,既无灵活性,代码又比较冗余,最弱
    • prototype,代码简洁语义,但无灵活性,中等
    • mootools,代码简洁语义,但无灵活性,中等
    • YUI,代码比较臃肿,但有较高灵活性,中等

    总之:简洁语义的实现 or 强大的功能,永远是一个平衡。

  • 相关阅读:
    MVC1
    Linux中的软连接与硬连接
    python之multiprocessing(二):multiprocessing.Pool
    python之multiprocessing(一)
    python之paramiko(一)
    python_Exception之:TypeError: 'int' object is not iterable
    python之socket(一)
    python之pymysql(一)
    生成树协议--STP
    路由协议--RIP
  • 原文地址:https://www.cnblogs.com/zxktxj/p/2723494.html
Copyright © 2020-2023  润新知