javascript 构建模块化开发过程解析


Posted in Javascript onSeptember 11, 2019

在使用 sea.js 、require.js 、 angular 的时候。

我们使用到 define 、 module(require) 的方式,定义模块,和依赖模块

下面给出 define 和 module 的简单实现。 其本质,就是往一个对象上面添加方法

var F = {};
F.define = function(str,fn){
  var parts = str.split(".");
  var parent = this; // parent 当前模块的父模块
  var i = len = 0;
  //如果第一个模块是模块单体对象,则移除
  if(parts[0] == "F"){
    parts = parts.slice(1);
  }
   
  //屏蔽对 define module 模块方法重写
  if(parts[0] == "define" || parts[0] == "module"){
    return ;
  }     
   
  for(len = parts.length; i < len-1; i++){
    //如果父模块中不存在当前模块
    if(typeof parent[parts[i]] === 'undefined'){
      //声明当前模块
      parent[parts[i]] = {};
    }
    //缓存下一层父模块
    parent = parent[parts[i]];
  }
   
  if(fn && parts[i]){
    //如果给定模块方法,则绑定该模块的方法,
    parent[parts[i]] = fn();
  }
  return this;
}
 
F.module = function(){
  var args = [].slice.call(arguments);//复制参数
  var fn = args.pop(); //获取回调
   
  var parts = args[0] && args[0] instanceof Array ? args[0] : args;
   
  //模块的依赖
  var modules = [];
   
  //模块的路由
  var modIDs = "";
   
  //依赖模块的索引
  var i = 0;
   
  var len = parts.length; // 依赖模块的长度
   
  var parent,j,jlen; //父级模块,模块路由层级索引,模块路由层级长度
   
  while(i < len){
    if(typeof parts[i] == "string"){
      parent = this;
      //解析路由,并且屏蔽掉 F
      modIDs = parts[i].replace(/^F\./,"").split(".");
      //遍历模块层级
      for( j = 0,jlen = modIDs.length; j < jlen; j++){
        //迭代 父模块
        parent = parent[modIDs[j]] || false;
      }
      modules.push(parent); //将模块添加到依赖列表
    }else{
      //直接将模块添加到依赖列表
      modules.push(parts[i]);
    }
    //取下一个模块
    i++;
  }
   
   
  //执行回调,将依赖的模块注入
  fn.apply(null,modules);  
} 
//定义 string 模块
F.define("string",function(){
  return {
    trim(str){
      return str.replace(/^s+|\s+$/g,"");
    }
  }
});
//定义 string 模块,的子模块 sub
F.define("string.sub",function(){
  return {
    low(str){
      return str.toLowerCase();
    }
  }
});
console.log(F);
//使用模块
F.module(["string","string.sub",document],function(str,strSub,doc){
  console.log(str,strSub,doc)
});

当然了,这里使用的,F 对象,实际应用中,应该写在闭包里面。不能让外界直接访问,于是有如下代码。

var Sea = (function(){
  var F = {};
    F.define = function(str,fn){
    var parts = str.split(".");
    var parent = this; // parent 当前模块的父模块
    var i = len = 0;
     
    //如果第一个模块是模块单体对象,则移除
    if(parts[0] == "F"){
      parts = parts.slice(1);
    }
     
    //屏蔽对 define module 模块方法重写
    if(parts[0] == "define" || parts[0] == "module"){
      return ;
    }     
     
    for(len = parts.length; i < len-1; i++){
      //如果父模块中不存在当前模块
      if(typeof parent[parts[i]] === 'undefined'){
        //声明当前模块
        parent[parts[i]] = {};
      }
      //缓存下一层父模块
      parent = parent[parts[i]];
    }
     
    if(fn && parts[i]){
      //如果给定模块方法,则绑定该模块的方法,
      parent[parts[i]] = fn();
    }
    return this;
  }
   
  F.module = function(){
    var args = [].slice.call(arguments);//复制参数
    var fn = args.pop(); //获取回调
     
    var parts = args[0] && args[0] instanceof Array ? args[0] : args;
     
    //模块的依赖
    var modules = [];
     
    //模块的路由
    var modIDs = "";
     
    //依赖模块的索引
    var i = 0;
     
    var len = parts.length; // 依赖模块的长度
     
    var parent,j,jlen; //父级模块,模块路由层级索引,模块路由层级长度
     
    while(i < len){
      if(typeof parts[i] == "string"){
        parent = this;
        //解析路由,并且屏蔽掉 F
        modIDs = parts[i].replace(/^F\./,"").split(".");
        //遍历模块层级
        for( j = 0,jlen = modIDs.length; j < jlen; j++){
          //迭代 父模块
          parent = parent[modIDs[j]] || false;
        }
        modules.push(parent); //将模块添加到依赖列表
      }else{
        //直接将模块添加到依赖列表
        modules.push(parts[i]);
      }
      //取下一个模块
      i++;
    }
     
     
    //执行回调,将依赖的模块注入
    fn.apply(null,modules);
  }
  return {
    define:function(){
      F.define.apply(F,arguments);
    },
    module:function(){
      F.module.apply(F,arguments);
    }
  }
})();
 
 
//定义 string 模块
Sea.define("string",function(){
  return {
    trim(str){
      return str.replace(/^s+|\s+$/g,"");
    }
  }
});
//定义 string 模块,的子模块 sub
Sea.define("string.sub",function(){
  return {
    low(str){
      return str.toLowerCase();
    }
  }
});
console.log(Sea);
//使用模块
Sea.module(["string","string.sub",document],function(str,strSub,doc){
  console.log(str,strSub,doc)
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript获取所有同类checkbox选项(实例代码)
Nov 07 Javascript
javascript中的正则表达式使用指南
Mar 01 Javascript
js实现网页抽奖实例
Aug 05 Javascript
jQuery中通过ajax调用webservice传递数组参数的问题实例详解
May 20 Javascript
AngularJS全局scope与Isolate scope通信用法示例
Nov 22 Javascript
JS对象是否拥有某属性如何判断
Feb 03 Javascript
微信小程序开发图片拖拽实例详解
May 05 Javascript
JS作用域链详解
Jun 26 Javascript
深入理解Angular中的依赖注入
Jun 26 Javascript
Vue中计算属性computed的示例解读
Jul 26 Javascript
tangram.js库实现js类的方式实例分析
Jan 06 Javascript
vue使用better-scroll实现滑动以及左右联动
Jun 30 Javascript
解决layer弹出层msg的文字不显示的问题
Sep 11 #Javascript
js贪心算法 钱币找零问题代码实例
Sep 11 #Javascript
解决layui使用layui-icon出现默认图标的问题
Sep 11 #Javascript
js图数据结构处理 迪杰斯特拉算法代码实例
Sep 11 #Javascript
js简单的分页器插件代码实例
Sep 11 #Javascript
解决在layer.open中使用时间控件laydate失败的问题
Sep 11 #Javascript
关于ckeditor在bootstrap中modal中弹框无法输入的解决方法
Sep 11 #Javascript
You might like
php仿QQ验证码的实例分析
2013/07/01 PHP
PHP实现无限分类的实现方法
2016/11/14 PHP
php str_replace替换指定次数的方法详解
2017/05/05 PHP
php转换上传word文件为PDF的方法【基于COM组件】
2019/06/10 PHP
jQuery DIV弹出效果实现代码
2009/07/03 Javascript
在IE下获取object(ActiveX)的Param的代码
2009/09/15 Javascript
解决javascript:window.close()在chrome,Firefox下失效的问题
2013/05/07 Javascript
js控制淡入淡出示例代码
2013/11/12 Javascript
Bootstrap 实现查询的完美方法
2016/10/26 Javascript
Bootstrap基本插件学习笔记之模态对话框(16)
2016/12/08 Javascript
vue 如何添加全局函数或全局变量以及单页面的title设置总结
2017/06/01 Javascript
使用vue + less 实现简单换肤功能的示例
2018/02/21 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
2018/07/20 Javascript
Vue.js中使用iView日期选择器并设置开始时间结束时间校验功能
2018/08/12 Javascript
Vue实现远程获取路由与页面刷新导致404错误的解决
2019/01/31 Javascript
JS使用数组实现的队列功能示例
2019/03/04 Javascript
layui弹出框Tab选项卡的示例代码
2019/09/04 Javascript
js实现滚动条自动滚动
2020/12/13 Javascript
[01:01:35]Optic vs paiN 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
python_opencv用线段画封闭矩形的实例
2018/12/05 Python
django模板结构优化的方法
2019/02/28 Python
Python CVXOPT模块安装及使用解析
2019/08/01 Python
python批量修改ssh密码的实现
2019/08/08 Python
使用Python的Turtle绘制哆啦A梦实例
2019/11/21 Python
Python并发请求下限制QPS(每秒查询率)的实现代码
2020/06/05 Python
基于python实现MQTT发布订阅过程原理解析
2020/07/27 Python
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
千禧酒店及度假村官方网站:Millennium Hotels and Resorts
2019/05/10 全球购物
加拿大的标志性百货公司:Hudson’s Bay(哈得逊湾)
2019/09/03 全球购物
三年级音乐教学反思
2014/01/28 职场文书
保卫钓鱼岛口号
2014/06/20 职场文书
国际贸易系求职信
2014/08/09 职场文书
学生自我鉴定格式及范文
2014/09/16 职场文书
2015年高中语文教学总结
2015/08/18 职场文书
《葡萄沟》教学反思
2016/02/23 职场文书
Python批量将csv文件转化成xml文件的实例
2021/05/10 Python