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 相关文章推荐
js中获取事件对象的方法小结
Mar 13 Javascript
通过JavaScript控制字体大小的代码
Oct 04 Javascript
php is_numberic函数造成的SQL注入漏洞
Mar 10 Javascript
jQuery动画出现连续触发、滞后反复执行的解决方法
Jan 28 Javascript
JavaScript编写检测用户所使用的浏览器的代码示例
May 05 Javascript
基于JS实现的笛卡尔乘积之商品发布
May 13 Javascript
JS输出空格的简单实现方法
Sep 08 Javascript
JavaScript中arguments和this对象用法分析
Aug 08 Javascript
使用Angular Cli如何创建Angular私有库详解
Jan 30 Javascript
微信小程序工具函数封装
Oct 28 Javascript
vue中使用router全局守卫实现页面拦截的示例
Oct 23 Javascript
记录一次websocket封装的过程
Nov 23 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合并数组+与array_merge的区别分析
2010/08/01 PHP
php中使用preg_match_all匹配文章中的图片
2013/02/06 PHP
php从数组中随机选择若干不重复元素的方法
2015/03/14 PHP
PHP数学运算与数据处理实例分析
2016/04/01 PHP
laravel通过创建自定义artisan make命令来新建类文件详解
2017/08/17 PHP
JavaScript中自定义事件用法分析
2014/12/23 Javascript
ECHO.js 纯javascript轻量级延迟加载的实例代码
2016/05/24 Javascript
jquery 动态增加删除行的简单实例(推荐)
2016/10/12 Javascript
div中文字内容溢出常见的解决方法
2017/03/16 Javascript
强大的 Angular 表单验证功能详细介绍
2017/05/23 Javascript
Angular.js项目中使用gulp实现自动化构建以及压缩打包详解
2017/07/19 Javascript
原生JS实现自定义滚动条效果
2020/10/27 Javascript
js截取字符串功能的实现方法
2017/09/27 Javascript
vue中导出Excel表格的实现代码
2018/10/18 Javascript
JSONP解决JS跨域问题的实现
2020/05/25 Javascript
js实现碰撞检测
2021/01/29 Javascript
[05:20]卡尔工作室_DOTA2新手教学_DOTA2超强新手功能
2013/04/22 DOTA
[01:37]全新的一集《真视界》——TI7总决赛
2017/09/21 DOTA
[02:40]2018年度DOTA2最佳新人-完美盛典
2018/12/16 DOTA
Python守护进程用法实例分析
2015/06/04 Python
python实现多线程行情抓取工具的方法
2018/02/28 Python
python将文本分每两行一组并保存到文件
2018/03/19 Python
Django url,从一个页面调到另个页面的方法
2019/08/21 Python
python3连接mysql获取ansible动态inventory脚本
2020/01/19 Python
OpenCV读取与写入图片的实现
2020/10/13 Python
HTML5 离线应用之打造零请求、无流量网站的解决方法
2013/04/25 HTML / CSS
Expedia泰国:预订机票、酒店和旅游包(航班+酒店)
2016/09/27 全球购物
美国折扣宠物药房:Total Pet Supply
2018/05/27 全球购物
英国领先的野生鸟类食品供应商:GardenBird
2018/08/09 全球购物
腾讯公司的一个sql题
2013/01/22 面试题
护士的岗位职责
2013/12/04 职场文书
车贷收入证明范本
2014/09/14 职场文书
2014年质检工作总结
2014/11/26 职场文书
校园音乐节目广播稿
2015/08/19 职场文书
5人制售《绝地求生》游戏外挂获利500多万元 被判刑
2022/03/31 其他游戏
MySQL数据库 任意ip连接方法
2022/05/20 MySQL