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 window.confirm确认 取消对话框实现代码小结
Oct 21 Javascript
extjs render 用法介绍
Sep 11 Javascript
javascript date格式化示例
Sep 25 Javascript
浅谈JavaScript中的Math.atan()方法的使用
Jun 14 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
Mar 17 Javascript
JavaScript String 对象常用方法总结
Apr 28 Javascript
Javascript中关于Array.filter()的妙用详解
Dec 04 Javascript
jQuery文字轮播特效
Feb 12 Javascript
基于iScroll实现内容滚动效果
Mar 21 Javascript
React SSR样式及SEO的实践
Oct 22 Javascript
JavaScript继承的特性与实践应用深入详解
Dec 30 Javascript
Javascript操作select控件代码实例
Feb 14 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
一个可查询所有表的“通用”查询分页类
2006/10/09 PHP
PHP封装的Twitter访问类实例
2015/07/18 PHP
PHP简单实现上一页下一页功能示例
2016/09/14 PHP
PHP递归算法的简单实例
2019/02/28 PHP
基于PHP实现堆排序原理及实例详解
2020/06/19 PHP
在JavaScript中通过URL传递汉字的方法
2007/04/09 Javascript
javascript小数计算出现近似值的解决办法
2010/02/06 Javascript
学习面向对象之面向对象的术语
2010/11/30 Javascript
js过滤特殊字符输入适合输入、粘贴、拖拽多种情况
2014/03/22 Javascript
js脚本实现数据去重
2014/11/27 Javascript
javascript 动态创建表格的2种方法总结
2015/03/04 Javascript
异步JavaScript编程中的Promise使用方法
2015/07/28 Javascript
js+canvas绘制五角星的方法
2016/01/28 Javascript
xtemplate node.js 的使用方法实例解析
2016/08/22 Javascript
微信小程序 wx.request(OBJECT)发起请求详解
2016/10/13 Javascript
JavaScript实现同一个页面打开多张图片
2016/12/29 Javascript
关于HTTP传输中gzip压缩的秘密探索分析
2018/01/12 Javascript
vue2.0 移动端实现下拉刷新和上拉加载更多的示例
2018/04/23 Javascript
浅谈关于vue中scss公用的解决方案
2019/12/02 Javascript
ES6中new Function()语法及应用实例分析
2020/02/19 Javascript
详解react组件通讯方式(多种)
2020/05/06 Javascript
JavaScript中的各种宽高属性的实现
2020/05/08 Javascript
Python自定义类的数组排序实现代码
2016/08/28 Python
python判断设备是否联网的方法
2018/06/29 Python
python绘制热力图heatmap
2020/03/23 Python
通过 Python 和 OpenCV 实现目标数量监控
2020/01/05 Python
tf.concat中axis的含义与使用详解
2020/02/07 Python
html5 localStorage本地存储_动力节点Java学院整理
2017/07/06 HTML / CSS
Engel & Bengel官网:婴儿推车、儿童房家具和婴儿设备
2019/12/28 全球购物
大学生自我鉴定书
2014/03/24 职场文书
化工专业自荐书
2014/06/16 职场文书
新闻编辑求职信
2014/07/13 职场文书
2014年祖国生日寄语
2014/09/19 职场文书
2014年卫生监督工作总结
2014/12/09 职场文书
详解MySQL 联合查询优化机制
2021/05/10 MySQL
Python正则表达式中flags参数的实例详解
2022/04/01 Python