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 字符串处理函数使用小结
Dec 02 Javascript
编写自己的jQuery插件简单实现代码
Apr 19 Javascript
Javascript 判断是否存在函数的方法
Jan 03 Javascript
JavaScript通过字典进行字符串翻译转换的方法
Mar 19 Javascript
javascript中递归函数用法注意点
Jul 30 Javascript
Validform+layer实现漂亮的表单验证特效
Jan 17 Javascript
使用JavaScript为Kindeditor自定义按钮增加Audio标签
Mar 18 Javascript
一览画面点击复选框后获取多个id值的方法
May 30 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
Dec 01 Javascript
JS前后端实现身份证号验证代码解析
Jul 23 Javascript
Vant Weapp组件踩坑:picker的初始赋值解决
Nov 12 Javascript
js不常见操作运算符总结
Nov 20 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聊天室技术
2006/10/09 PHP
PHP禁止页面缓存的代码
2011/10/23 PHP
php采集神器cURL使用方法详解
2016/02/19 PHP
Win7环境下Apache连接MySQL提示连接已重置的解决办法
2017/05/09 PHP
特殊字符、常规符号及其代码对照表
2006/06/26 Javascript
js检测客户端不是firefox则提示下载
2007/04/07 Javascript
javascript 文档的编码问题解决
2009/03/01 Javascript
js 有框架页面跳转(target)三种情况下的应用
2013/04/09 Javascript
JS时间特效最常用的三款
2015/08/19 Javascript
第一篇初识bootstrap
2016/06/21 Javascript
javascript设计模式之module(模块)模式
2016/08/19 Javascript
浅谈Angular.js中使用$watch监听模型变化
2017/01/10 Javascript
微信小程序如何实现精确的日期时间选择器
2020/01/21 Javascript
[02:31]2014DOTA2国际邀请赛2009专访:干爹表现出乎意料 看好DK杀回决赛
2014/07/20 DOTA
[15:56]Heroes18_暗影萨满(完美)
2014/10/31 DOTA
[10:39]DOTA2上海特级锦标赛音乐会纪录片
2016/03/21 DOTA
python 解析html之BeautifulSoup
2009/07/07 Python
Django框架搭建的简易图书信息网站案例
2019/05/25 Python
python 随机生成10位数密码的实现代码
2019/06/27 Python
python正则-re的用法详解
2019/07/28 Python
Python partial函数原理及用法解析
2019/12/11 Python
Python:__eq__和__str__函数的使用示例
2020/09/26 Python
基于CSS3实现的漂亮Menu菜单效果代码
2015/09/10 HTML / CSS
亚洲最大的眼镜批发商和零售商之一:Glasseslit
2018/10/08 全球购物
毕业生医学检验求职信
2013/10/16 职场文书
店长岗位的工作内容
2013/11/12 职场文书
民生工程实施方案
2014/03/22 职场文书
卫生系统先进事迹
2014/05/13 职场文书
相亲大会策划方案
2014/06/05 职场文书
惊涛骇浪观后感
2015/06/05 职场文书
反腐倡廉观后感
2015/06/08 职场文书
《你在为谁工作》心得体会(共8篇)
2016/01/20 职场文书
妇产科护理心得体会
2016/01/22 职场文书
2019年房屋委托租赁合同范本(通用版)!
2019/07/17 职场文书
用python自动生成日历
2021/04/24 Python
浅谈自定义校验注解ConstraintValidator
2021/06/30 Java/Android