欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

javascript 构建模块化开发过程解析

程序员文章站 2022-05-07 09:33:55
在使用 sea.js 、require.js 、 angular 的时候。 我们使用到 define 、 module(require) 的方式,定义模块,和依赖模块...

在使用 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)
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。