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 相关文章推荐
多个iframe自动调整大小的问题
Sep 18 Javascript
javascript笔记 String类replace函数的一些事
Sep 22 Javascript
JavaScript比较两个对象是否相等的方法
Feb 06 Javascript
网页挂马方式整理及详细介绍
Nov 03 Javascript
jQuery简单绑定单个事件的方法示例
Jun 10 jQuery
easyui datagrid 表格中操作栏 按钮图标不显示的解决方法
Jul 27 Javascript
详解vue 组件之间使用eventbus传值
Oct 25 Javascript
vue自定义过滤器创建和使用方法详解
Nov 06 Javascript
vue基础之使用get、post、jsonp实现交互功能示例
Mar 12 Javascript
详解微信小程序的不同函数调用的几种方法
May 08 Javascript
EasyUI 数据表格datagrid列自适应内容宽度的实现
Jul 18 Javascript
Openlayers实现地图的基本操作
Sep 28 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面向对象全攻略 (五) 封装性
2009/09/30 PHP
解读PHP中上传文件的处理问题
2016/05/29 PHP
JavaScript 全面解析各种浏览器网页中的JS 执行顺序
2009/02/17 Javascript
javascript去除字符串左右两端的空格
2015/02/05 Javascript
jQuery实现Flash效果上下翻动的中英文导航菜单代码
2015/09/22 Javascript
jQuery实现链接的title快速出现的方法
2017/02/20 Javascript
js弹性势能动画之抛物线运动实例详解
2017/07/27 Javascript
vue2.0 中使用transition实现动画效果使用心得
2018/08/13 Javascript
vue项目上传Github预览的实现示例
2018/11/06 Javascript
微信小程序实现点击卡片 翻转效果
2019/09/04 Javascript
深入解析Python中的变量和赋值运算符
2015/10/12 Python
深入讲解Java编程中类的生命周期
2016/02/05 Python
Python实现求笛卡尔乘积的方法
2017/09/16 Python
python爬虫之线程池和进程池功能与用法详解
2018/08/02 Python
学生信息管理系统python版
2018/10/17 Python
Python实现快速排序的方法详解
2019/10/25 Python
3种适用于Python的疯狂秘密武器及原因解析
2020/04/29 Python
Django之全局使用request.user.username的实例详解
2020/05/14 Python
Python爬虫之Spider类用法简单介绍
2020/08/04 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
2020/09/28 Python
Django contrib auth authenticate函数源码解析
2020/11/12 Python
纯CSS实现右侧底部悬浮效果(悬浮QQ、微信、微博、邮箱等联系方式)
2015/04/24 HTML / CSS
馥绿德雅美国官方网站:Rene Furterer头皮护理专家
2019/05/01 全球购物
BudgetAir印度:预订航班、酒店和汽车租赁
2019/07/07 全球购物
行政经理岗位职责
2013/11/09 职场文书
运动会演讲稿50字
2014/08/25 职场文书
会员卡清退活动总结
2014/08/27 职场文书
解放思想演讲稿
2014/09/11 职场文书
财务人员岗位职责
2015/02/03 职场文书
2015年助残日活动总结
2015/03/27 职场文书
高中历史教学反思
2016/02/19 职场文书
2016年小学六一儿童节活动总结
2016/04/06 职场文书
八年级作文之友情
2019/11/25 职场文书
redis实现共同好友的思路详解
2021/05/26 Redis
详解Python描述符的工作原理
2021/06/11 Python
SQL语句多表联合查询的方法示例
2022/04/18 MySQL