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 相关文章推荐
兼容IE和Firefox的javascript获取iframe文档内容的函数
Aug 15 Javascript
将数字转换成大写的人民币表达式的js函数
Sep 21 Javascript
javascript控制层显示或隐藏的方法
Jul 22 Javascript
javascript函数式编程程序员的工具集
Oct 11 Javascript
基于JavaScript实现在新的tab页打开url
Aug 04 Javascript
js判断请求的url是否可访问,支持跨域判断的实现方法
Sep 17 Javascript
Vue 组件(component)教程之实现精美的日历方法示例
Jan 08 Javascript
vue自定义一个v-model的实现代码
Jun 21 Javascript
javascript实现简易的计算器
Jan 17 Javascript
vue内置组件keep-alive事件动态缓存实例
Oct 30 Javascript
超详细小程序定位地图模块全系列开发教学
Nov 24 Javascript
vue组件中节流函数的失效的原因和解决方法
Dec 02 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
用DBSQL类加快开发MySQL数据库程序的速度
2006/10/09 PHP
php面向对象全攻略 (七) 继承性
2009/09/30 PHP
PHP中PDO的错误处理
2011/09/04 PHP
php画图实例
2014/11/05 PHP
php使用curl简单抓取远程url的方法
2015/03/13 PHP
PHPStudy下如何为Apache安装SSL证书的方法步骤
2019/01/23 PHP
PHP7 整型处理机制修改
2021/03/09 PHP
js技巧--转义符&quot;\&quot;的妙用
2007/01/09 Javascript
js中的值类型和引用类型小结 文字说明与实例
2010/12/12 Javascript
ajax java 实现自动完成功能
2012/12/19 Javascript
jquery提示效果实例分析
2014/11/25 Javascript
javascript中AJAX用法实例分析
2015/01/30 Javascript
javascript数组遍历的方法实例分析
2016/09/13 Javascript
Bootstrap企业网站实战项目4
2016/10/14 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
2016/11/30 Javascript
js仿微信语音播放实现思路
2016/12/12 Javascript
JavaScript验证知识整理
2017/03/24 Javascript
微信小程序 页面滑动事件的实例详解
2017/10/12 Javascript
JS抛物线动画实例制作
2018/02/24 Javascript
vue移动端使用canvas签名的实现
2020/01/15 Javascript
vue 点击其他区域关闭自定义div操作
2020/07/17 Javascript
一个简单的python程序实例(通讯录)
2013/11/29 Python
Python新手在作用域方面经常容易碰到的问题
2015/04/03 Python
运用Python的webbrowser实现定时打开特定网页
2019/02/21 Python
如何基于pythonnet调用halcon脚本
2020/01/20 Python
如何利用pycharm进行代码更新比较
2020/11/04 Python
python中PyQuery库用法分享
2021/01/15 Python
Myprotein瑞典官方网站:畅销欧洲英国运动营养品牌
2018/01/22 全球购物
美国精油公司:Plant Therapy
2019/05/17 全球购物
公共汽车、火车和飞机票的通用在线预订和销售平台:INFOBUS
2019/11/30 全球购物
Moda Operandi官网:美国奢侈品电商,海淘秀场T台同款
2020/05/26 全球购物
学校介绍信范文
2014/01/14 职场文书
大学军训感言800字
2014/02/27 职场文书
出生公证委托书
2014/04/03 职场文书
2014年销售工作总结范文
2014/12/01 职场文书
世界名著读书笔记
2015/06/25 职场文书