commonjs规范

2022-09-03  本文已影响0人  5cc9c8608284

模块的导出和模块的导入

什么是模块?

模块就是一个js文件,它实现了一部分功能,并隐藏自己的内部实现,同时提供了一些接口供其他模块使用。

模块有两个核心的要素:隐藏和暴露

隐藏的是自己内部的实现
暴露的是希望外部使用的接口

模块的导出

任何一个正常的模块化标准,都应该默认默认隐藏模块内的所有实现,而通过一些语法或者api调用来暴露接口
暴露接口的过程即模块的导出

模块的导入

当需要使用一个模块时,使用的是该模块暴露的模块(导出的模块),隐藏的部分是永远无法使用的
当通过某种语法或api去使用一个模块时,这个过程叫做模块的导入

CommonJS规范

CommonJS使用exports导出模块,require导入模块
具体规范如下:
1.如果一个JS文件中存在exports或require,该JS文件是一个模块
2.模块内的所有代码均为隐藏代码,包括全局变量、全局函数,这些全局的内容均不应该对全局变量造成任何污染
3.如果一个模块需要暴露一些API提供给外部使用,需要通过exports导出,exports是一个空的对象,你可以为该对象添加任何需要导出的内容
4.如果一个模块需要导入其他模块,通过require实现,require是一个函数,传入模块的路径即可返回该模块导出的整个内容
举个栗子:
demo1.js

var count=0;//需要隐藏的内部实现
// 要暴露给外部的接口
function getNumber(){
  count++;
  return count;
}

//exports是一个空对象 exports={}
exports.getNumber=getNumber;
/**
 * exports:{
 * getNumber:getNumber
 * }
 */

 exports.name='zhangsan'


//  最后导出的对象
 /**
 * exports:{
 * getNumber:getNumber,
 * name:'zhangsan'
 * }
 */

demo2.js

//nodejs中导入模块,使用相对路径导入,并且必须以./或者../开头
const a=require('./demo1.js');
console.log(a.getNumber(),'getNumber');//1 getNumber
console.log(a.name,'name');//zhangsan  name

nodejs对CommonJS的实现

为了实现CommonJS规范,nodejs对模块做出了以下处理

1.为了保证高效的执行,仅加载必要的模块。nodejs只有执行到require函数时才会加载并执行模块

2.为了隐藏模块中的代码,nodejs执行模块时,会将模块中的所有代码放置到一个函数中执行,以保证不污染全局变量。

 (function(){
     //模块中的代码
 })()

3.为了保证顺利的导出模块内容,nodejs做了以下处理

在模块开始执行前,初始化一个值module.exports = {}
module.exports即模块的导出值
为了方便开发者便捷的导出,nodejs在初始化完module.exports后,又声明了一个变量exports = module.exports

 (function(module){
     module.exports = {};
     var exports = module.exports;
     //模块中的代码
     return module.exports;
 })()

举个栗子来说:

(function(module){
 module.exports={}
 var exports=module.exports;
 var count=0;
 function getNumber(){
   count++
   return count;
 }
 exports.getNumber=getNumber;
 exports.name='zhangsna1';
 return module.exports;
})()

4.为了避免反复加载同一个模块,nodejs默认开启了模块缓存,如果加载的模块已经被加载过了,则会自动使用之前的导出结果

练习题

制作一个斗地主洗牌发牌的程序

划分模块:

  1. 工具模块,导出一个函数,用于将一个数组中的所有内容乱序排列
  2. 扑克牌构造函数(类)
    1. 属性
      1. 花色(1~4,♣、♥、♦、♠)
      2. 牌面(1~15,14小王,15大王)
    2. 方法
      1. toString:得到该扑克牌的字符串
  3. 入口模块(入口文件)
    1. 创建54张扑克牌
    2. 洗牌
    3. 发牌
      utils.js(工具文件)
// 工具函数
module.exports={
  /**
   * 
   * @param {*} arr 数组
   */
  sortRandomArr(arr){
    arr.sort((a,b)=>{
      return Math.random()-0.5
    })
  },
  /**
   * 打印一个扑克拍的数组
   * @param {*} pokers 数组
   * 
   */
  print(pokers){
    for(let i=0;i<pokers.length;i++){
      var str='';
      var p=pokers[i];
      str+=p.toString()+' ';
      console.log(str);
    }
  }
}

pokers.js

// 扑克相关
function Poker(color,number){
//  color:花色
// number:数字
this.color=color;
this.number=number;
}
Poker.prototype.toString=function(){
  /**
   *  1. 花色(1~4,♣、♥、♦、♠)
      2. 牌面(1~15,14小王,15大王)
   */
  var str='';
  if(this.color==1){
    str+='♣';
  }else if(this.color==2){
    str+='♥';
  }else if(this.color==3){
    str+='♦';
  }else{
    str+='♠';
  }

  if(this.number>=2&&this.number<=10){
    str+=this.number;
  }
else if(this.number==1){
  str+='A'
}else if(this.number==11){
  str+='J';
}else if(this.number==12){
  str+='Q';
}else if(this.number==13){
  str+='K';
}else if(this.number==14){
  str='joker';
}else if(this.number===15){
  str='JOKER';
}
return str;
}

//导出构造函数
module.exports=Poker;

index.js(入口文件)

//入口文件
const Poker=require('./poker.js');
let pokers=[];//扑克牌数组
for(let i=1;i<=13;i++){//牌面
  for(let j=1;j<=4;j++){//花色
    pokers.push(new Poker(j,i))
  }
}

// 大王小王
pokers.push(new Poker(null,14),new Poker(null,15))
for(let i=0;i<pokers.length;i++){
  let p=pokers[i];
}


// 打乱数组
const utils=require('./utils.js');
utils.sortRandomArr(pokers);


//发牌
var player1=pokers.slice(0,17);
var player2=pokers.slice(17,34);
var player3=pokers.slice(34,51);
var desk=pokers.slice(51);

//打印玩家的牌
console.log('玩家1:');
utils.print(player1);

console.log('玩家2:');
utils.print(player2)

console.log('玩家3:');
utils.print(player3)
上一篇下一篇

猜你喜欢

热点阅读