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 小数取整的函数
May 10 Javascript
读jQuery之一(对象的组成)
Jun 11 Javascript
node.js中的buffer.Buffer.isEncoding方法使用说明
Dec 14 Javascript
Highcharts学习之坐标轴
Aug 02 Javascript
Vue.js 2.0窥探之Virtual DOM到底是什么?
Feb 10 Javascript
Bootstrap 响应式实用工具实例详解
Mar 29 Javascript
基于Vue实现页面切换左右滑动效果
Jun 29 Javascript
JavaScript使用享元模式实现文件上传优化操作示例
Aug 07 Javascript
fetch 如何实现请求数据
Dec 20 Javascript
详解如何运行vue项目
Apr 15 Javascript
vue实现选中效果
Oct 07 Javascript
三种方式清除vue路由跳转router-link的历史记录
Apr 10 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 错误之引号中使用变量
2009/05/04 PHP
php模拟asp中的XmlHttpRequest实现http请求的代码
2011/03/24 PHP
浅析PHP递归函数返回值使用方法
2013/02/18 PHP
php防注入及开发安全详细解析
2013/08/09 PHP
Codeigniter的一些优秀特性总结
2015/01/21 PHP
深入理解PHP之OpCode原理详解
2016/06/01 PHP
PHP-CGI远程代码执行漏洞分析与防范
2017/05/07 PHP
jquery form表单提交插件asp.net后台中文解码
2010/06/12 Javascript
javascript内置对象操作详解
2015/02/04 Javascript
使用AngularJS来实现HTML页面嵌套的方法
2015/06/17 Javascript
AngularJS使用$http配置对象方式与服务端交互方法
2018/08/13 Javascript
Vue插件打包与发布的方法示例
2018/08/20 Javascript
解决VUE 在IE下出现ReferenceError: Promise未定义的问题
2020/11/07 Javascript
[04:50]2019DOTA2高校联赛秋季赛四强集锦
2019/12/27 DOTA
Python处理RSS、ATOM模块FEEDPARSER介绍
2015/02/18 Python
在Python下进行UDP网络编程的教程
2015/04/29 Python
Python变量作用范围实例分析
2015/07/07 Python
详解Python中映射类型(字典)操作符的概念和使用
2015/08/19 Python
Python自动发邮件脚本
2017/03/31 Python
Django使用Mysql数据库已经存在的数据表方法
2018/05/27 Python
Python OpenCV 调用摄像头并截图保存功能的实现代码
2019/07/02 Python
基于python的itchat库实现微信聊天机器人(推荐)
2019/10/29 Python
Python scrapy爬取小说代码案例详解
2020/07/09 Python
纯CSS3实现地球自转实现代码(图文教程附送源码)
2012/12/26 HTML / CSS
HTML5实践-图片设置成灰度图
2012/11/12 HTML / CSS
sort命令的作用和用法
2012/11/04 面试题
AssertionError 跟一下那个类是 “is – a”的关系
2012/02/21 面试题
数字化校园建设方案
2014/05/03 职场文书
学校爱国卫生月活动总结
2014/06/25 职场文书
个人四风问题对照检查材料思想汇报
2014/10/06 职场文书
先进教育工作者事迹材料
2014/12/23 职场文书
佛光寺导游词
2015/02/10 职场文书
学期个人自我总结
2015/02/13 职场文书
php中配置文件保存修改操作 如config.php文件的读取修改等操作
2021/05/12 PHP
Java Spring 控制反转(IOC)容器详解
2021/10/05 Java/Android
JS 基本概念详细介绍
2021/10/16 Javascript