CommonJS

一、CommonJS

在nodejs中,由于有且仅有一个入口文件(启动文件),而开发一个应用肯定会涉及到多个文件配合,因此,nodejs对模块化的需求比浏览器端要大的多
在这里插入图片描述
由于nodejs刚刚发布的时候,前端没有统一的、官方的模块化规范,因此,它选择使用社区提供的CommonJS作为模块化规范

在学习CommonJS之前,首先认识两个重要的概念:模块的导出模块的导入

1.模块的导出

要理解模块的导出,首先要理解模块的含义
什么是模块?

模块就是一个JS文件,它实现了一部分功能,并隐藏自己的内部实现,同时提供了一些接口供其他模块使用
模块有两个核心要素:隐藏暴露

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

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

暴露接口的过程即模块的导出
在这里插入图片描述

2.模块的导入

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

3.CommonJS规范

CommonJS使用exports导出模块,require导入模块

具体规范如下:

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

4.nodejs对CommonJS的实现

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

  1. 为了保证高效的执行,仅加载必要的模块。nodejs只有执行到require函数时才会加载并执行模块
  2. 为了隐藏模块中的代码,nodejs执行模块时,会将模块中的所有代码放置到一个函数中执行,以保证不污染全局变量。
(function(){
    //模块中的代码
})()
  1. 为了保证顺利的导出模块内容,nodejs做了以下处理
    1. 在模块开始执行前,初始化一个值module.exports = {}
    2. module.exports即模块的导出值
    3. 为了方便开发者便捷的导出,nodejs在初始化完module.exports后,又声明了一个变量exports = module.exports
(function(module){
    module.exports = {};
    var exports = module.exports;
    //模块中的代码
    return module.exports;
})()
  1. 为了避免反复加载同一个模块,nodejs默认开启了模块缓存,如果加载的模块已经被加载过了,则会自动使用之前的导出结果

5.实例

//index.js中
//nodejs中导入模块,使用相对路径,并且必须以./或../开头
const util = require("./util.js");
//util.js中
var count = 0; //需要隐藏的内部实现
console.log("util模块执行了!");
exports.getCount = function (){
    count ++;
    console.log('count被输出:'+count);
};
exports.count = count;

在这里插入图片描述

//util.js中
var count = 0; //需要隐藏的内部实现
console.log("util模块执行了!");
module.exports.getCount = function (){
    count ++;
    console.log('count被输出:'+count);
};
module.exports.count = count;

在这里插入图片描述

var count = 0; //需要隐藏的内部实现
console.log("util模块执行了!");
module.exports = {//该方式更常用
    getCount: function (){
        count ++;
        console.log('count被输出:'+count);
    },
    str: 'jimo'
}

6.练习

制作一个斗地主洗牌发牌的程序
划分模块:

1. 工具模块,导出一个函数,用于将一个数组中的所有内容乱序排列
2. 扑克牌构造函数(类)
   1. 属性
      1. 花色(1~4,♣、♥、♦、♠)
      2. 牌面(1~1514小王,15大王)
   2. 方法
      1. toString:得到该扑克牌的字符串
3. 入口模块(入口文件)
   1. 创建54张扑克牌
   2. 洗牌
   3. 发牌
//index.js启动板块
var pokers = []; //扑克牌的数组
var Poker = require("./poker") //导入扑克牌的构造函数
for(var j = 1;j <= 13;j ++){
    for(var i = 1;i <= 4;i ++){
        pokers.push(new Poker(i,j));
    }
};
pokers.push(new Poker(null, 14), new Poker(null, 15));
var util = require('./util');//导入洗牌发牌功能
util.sortRandom(pokers);//洗牌

var player1 = pokers.slice(0, 18);//人数牌数
var player2 = pokers.slice(18, 36);
var player3 = pokers.slice(36);

util.print(player1);//发牌
util.print(player2);
util.print(player3);
//poker.js扑克牌的构造函数
function Poker(color,number){
    this.number = number;
    this.color = color;
};
Poker.prototype.createPoke = function(){
    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;
//util洗牌发牌
module.exports = {
    sortRandom: function (arr) {//洗牌
        arr.sort(function (a, b) {
            return Math.random() - 0.5;
        })
    },
    print: function (pokers) {//发牌
        var str = "";
        for (var i = 0; i < pokers.length; i++) {
            var p = pokers[i];
            str += p.createPoke() + "   ";
        }
        console.log(str);
    }
};

在这里插入图片描述
这里可以继续丰富完善,比如洗牌后,发牌到牌手时会自动排序等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞羽逐星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值