Javascript模块化开辟-轻盈克己

一、媒介

现在javascript的盛行,前端的代码愈来愈庞杂,所以我们须要软件工程的头脑来开辟前端。模块化是必不可少的,如许不仅能够进步代码的可维护性、可扩展性以及鲁棒性,更大的优点就是能够提拔全部团队的开辟效力,也能够让新进的顺序员更快的接办事情。本日晚上依据先辈们的履历,写啦一个简朴的模块定义的封装组件,当是练手吧。不过觉得照样蛮好用的。

二、进修模块化前我们应当先相识点什么呢?

实在倏忽就进修模块化的javascript开辟,那照样比较丈二和尚,摸不着头脑的。不过假如是做过背景开辟的顺序员们,能够关于模块化的开辟头脑并不生疏,由于背景的这方面手艺已很熟悉了。那末这里我就分享一下前端javascript模块化开辟的进修。

1. 相识模块化开辟头脑

假如有软件工程背景,那末这一头脑就是你本身就应当控制的。模块(module)就是能够组合、剖析以及替换的单位,实在也满足组合大于继续等这些带来的优点吧。假如算作一个体系的话,我们能够从软件体系结构来明白,模块是较大体系中的自力部件,功用、状况与接口反应外部特征,逻辑反应的是内部特征。

2. 相识前端模块化开辟带来的优点

模块化的开辟形式为前端带来了新大陆,这点不能不认可,现在前端的越发成熟,须要软件工程的这类头脑。
玉伯也宣布过前端模块化开辟的代价

3.相识现在手艺,哪些和模块化开辟沾边

1) 开辟功用模块的时刻,能够采纳Eva的解决方案(YUI3 + Minify)。

2) 运用盛行的javascript模块加载框架:seajs。

3) 假如喜好轻盈的东西,也能够尝试带刀easy.js,不错的一个模块加载框架。

4) 也能够尝试支付宝的Alice,这是一款基于CMD类型的东东,首页却是挺小清新的。

5) 现在比较火的NodeJS这是必需要相识和进修的。

好啦,相识完上面那些手艺后,模块化的前端形式应当很熟悉了,假如想踏实一下的话还能够相识一下AMD、CMD类型,详细是什么东西,google一下。接下来我们就来组织一个简朴的模块定义器吧,实在写的时刻还挺简朴的,不过主如果吸取头脑,如许进修手艺才不会跟不上时期。

三、轻盈类型

1. 模块的数据结构(JSON示意)

module: {
    //模块称号
    moduleName: moduleName,
    //模块依靠鸠合
    dependencies: dependencies,
    //模块实例工场
    factory: factory
}

2. 模块定义

所以我们末了能够构成模块定义的代码以下:

define: function ( moduleName, dependencies, factory ) {
    if( !modules[moduleName] ) {
        //模块信息
        var module = {
            moduleName: moduleName,
            dependencies: dependencies,
            factory: factory
        };

        modules[moduleName] = module;
    }

    return modules[moduleName];
}

3. 模块挪用

如许我们就定义好了模块,那末我们的进口在那里呢?我们还须要定义一个use的要领,来成为所谓的main,如许绑定好了才能够挪用,现在想来顺序也都是如许的。下面这段代码经由过程递归的发生模块依靠的一切实例,然则这里浪费了一部分instances数组的空间,有时间能够再做哈优化。

use: function ( moduleName ) {
    //运用括号的体式格局接见属性,完成动态的赋值(概况查阅“.”和[]的区分)
    var module = modules[moduleName];

    //发生单个实例
    if( !module.instance ) {
        var instances = [], 
            len = module.dependencies.length - 1;

            for( var i = 0; i <= len; i++ ) {
                var dependency = module.dependencies[i],
                    instance = dependency.instance;

                if( instance ) {
                    instances.push( instance );
                } else {
                    //递归,将每次发生的实例放入数组
                    instances.push( arguments.callee( dependency ) );
                }
            }
            //天生实例
            module.instance = module.factory.apply( null, instances );
    }

    return module.instance;
}
 

4. 完全代码

末了我构成完全的本身的小库。

(function ( window, undefined ) {
    var modules = {};
    var Sky = {
        //定义模块的基本信息
        //1.模块称号,2.模块的依靠,3.发生实例的工场
        define: function ( moduleName, dependencies, factory ) {
            if( !modules[moduleName] ) {
                //模块信息
                var module = {
                    moduleName: moduleName,
                    dependencies: dependencies,
                    factory: factory
                };

                modules[moduleName] = module;
            }

            return modules[moduleName];
        },
        //运用依靠
        use: function ( moduleName ) {
            var module = modules[moduleName];

            //发生单个实例
            if( !module.instance ) {
                var instances = [], 
                    len = module.dependencies.length - 1;

                for( var i = 0; i <= len; i++ ) {
                    var dependency = module.dependencies[i],
                        instance = dependency.instance;

                    if( instance ) {
                        instances.push( instance );
                    } else {
                        //递归,将每次发生的实例放入数组
                        instances.push( arguments.callee( dependency ) );
                    }
                }
                //天生实例
                module.instance = module.factory.apply( null, instances );
            }

            return module.instance;
        }
    };

    window.Sky = Sky || {};
})(window);

下面我们来一个完全的例子来运用一下以上我们构建的轻盈代码。

Sky.define("constant.PI", [], function() {
    return 3.1415926;
});

Sky.define("shape.Circle", ["constant.PI"], function( pi ) {
    function Circle(r) {
        this.r = r || 0;
    };

    Circle.prototype.area = function() {
        return pi * this.r * this.r;
    };

    return Circle;
});

Sky.define("shape.Rectangle", [], function() {
    function Rectangle(width, height) {
        this.width = width || 0;
        this.height = height || 0;
    };

    Rectangle.prototype.area = function() {
        return this.width * this.height;
    };

    return Rectangle;
});

Sky.define("ShapeTypes", ["shape.Circle", "shape.Rectangle"], function( Circle, Rectangle ) {
    return {
        'CIRCLE': Circle,
        'RECTANGLE': Rectangle
    };
});

Sky.define("ShapeFactory", ["ShapeTypes"], function( ShapeTypes ) {
    return {
        getShape: function(type) {
            var shape;

            switch (type) {
            case 'CIRCLE':
                shape = new ShapeTypes[type](arguments[1]);
                break;
            case 'RECTANGLE':
                shape = new ShapeTypes[type](arguments[1], arguments[2]);
                break;
            }
            return shape;
        }
    };
});

var ShapeFactory = Sky.use("ShapeFactory");
console.log(ShapeFactory.getShape("CIRCLE").area());
console.log(ShapeFactory.getShape("RECTANGLE", 2, 3).area());

是否是觉得js代码变得越发清新了?嘿嘿,上面的例子也是面向接口的,人人也能够看看。

参考先辈:http://blog.jobbole.com/43649/

或许代码有相差,有些处所先辈写得不够仔细的我补上了一些,嘿嘿,然则思绪是参考这位先辈的。

原文出自:http://www.60sky.com/

    原文作者:小撸
    原文地址: https://segmentfault.com/a/1190000004044727
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞