zoukankan      html  css  js  c++  java
  • 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 强大的功能,永远是一个平衡。

  • 相关阅读:
    Using Resource File on DotNet
    C++/CLI VS CSharp
    JIT VS NGen
    [Tip: disable vc intellisense]VS2008 VC Intelisense issue
    UVa 10891 Game of Sum(经典博弈区间DP)
    UVa 10723 Cyborg Genes(LCS变种)
    UVa 607 Scheduling Lectures(简单DP)
    UVa 10401 Injured Queen Problem(简单DP)
    UVa 10313 Pay the Price(类似数字分解DP)
    UVa 10635 Prince and Princess(LCS N*logN)
  • 原文地址:https://www.cnblogs.com/zxktxj/p/2723494.html
Copyright © 2011-2022 走看看