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的面向对象(一)
Nov 09 Javascript
JQUERY 浏览器判断实现函数
Aug 20 Javascript
JavaScript高级程序设计 XML、Ajax 学习笔记
Sep 10 Javascript
jQuery实现高亮显示的方法
Mar 10 Javascript
javascript实现tab切换的四种方法
Nov 05 Javascript
快速掌握Node.js中setTimeout和setInterval的使用方法
Mar 21 Javascript
jQuery的层级查找方式分析
Jun 16 Javascript
最原始的jQuery注册验证方式
Oct 11 Javascript
js实现下拉菜单效果
Mar 01 Javascript
vue解决弹出蒙层滑动穿透问题的方法
Sep 22 Javascript
微信小程序实现禁止分享代码实例
Oct 19 Javascript
Vue +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例
Nov 18 Vue.js
解决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/12/06 PHP
浅析ThinkPHP中execute和query方法的区别
2014/06/13 PHP
ThinkPHP3.1查询语言详解
2014/06/19 PHP
BOM与DOM的区别分析
2010/10/26 Javascript
jQuery效果 slideToggle() 方法(在隐藏和显示之间切换)
2011/06/28 Javascript
jQuery .attr()和.removeAttr()方法操作元素属性示例
2013/07/16 Javascript
基于JQuery实现的图片自动进行缩放和裁剪处理
2014/01/31 Javascript
使用jQuery简单实现模拟浏览器搜索功能
2014/12/21 Javascript
基于jquery步骤进度条源码分享
2015/11/12 Javascript
JS实现动态生成表格并提交表格数据向后端
2020/11/25 Javascript
js HTML5 Ajax实现文件上传进度条功能
2016/02/13 Javascript
基于JS实现移动端访问PC端页面时跳转到对应的移动端网页
2020/12/24 Javascript
jQuery点击输入框显示验证码图片
2016/05/19 Javascript
前端微信支付js代码
2016/07/25 Javascript
js中Number数字数值运算后值不对的解决方法
2017/02/28 Javascript
详解从零搭建 vue2 vue-router2 webpack3 工程
2017/11/22 Javascript
jQuery实现使用sort方法对json数据排序的方法
2018/04/17 jQuery
Vue点击切换颜色的方法
2018/09/13 Javascript
详解解决小程序中webview页面多层history返回问题
2019/08/20 Javascript
JQuery 实现文件下载的常用方法分析
2019/10/29 jQuery
[02:54]DOTA2英雄基础教程 撼地者
2014/01/14 DOTA
[05:22]DOTA2 2015国际邀请赛中国区预选赛首日TOP10
2015/05/26 DOTA
Python编程语言的35个与众不同之处(语言特征和使用技巧)
2014/07/07 Python
python3 拼接字符串的7种方法
2018/09/12 Python
详解Python3除法之真除法、截断除法和下取整对比
2019/05/23 Python
python实现画出e指数函数的图像
2019/11/21 Python
浅谈python输出列表元素的所有排列形式
2020/02/26 Python
卡塔尔航空官方网站:Qatar Airways
2017/02/08 全球购物
The North Face北面荷兰官网:美国著名户外品牌
2019/10/16 全球购物
SmartBuyGlasses荷兰:购买太阳镜和眼镜
2020/03/16 全球购物
大学生村官心得体会范文
2014/01/04 职场文书
司仪主持词两篇
2014/03/22 职场文书
好听的队名和口号
2014/06/09 职场文书
围城读书笔记
2015/06/26 职场文书
贴吧吧主申请感言
2015/08/03 职场文书
css3中2D转换之有趣的transform形变效果
2022/02/24 HTML / CSS