Node.js学习笔记(二)——CommonJS规范

一、前言

ECMAScript标准的缺陷

  • 没有模块系统
  • 标准库较少
  • 没有标准接口
  • 缺乏管理系统

模块化

  • 如果程序设计的规模达到了一定程度,则必须对其进行模块化。
  • 模块化可以有多种形式,但至少应该提供能够将代码分割为多个源文件的机制。
  • CommonJS 的模块功能可以帮我们解决该问题。

注意

  • 在Node中,一个js文件就是一个模块
  • 在Node中,每一个js文件中的js代码都是独立运行在一个函数中,而不是全局作用域中,所以一个模块的中的变量和函数在其他模块中无法访问

二、CommonJS规范

  • CommonJS规范的提出,主要是为了弥补当前JavaScript没有模块化标准的缺陷。
  • CommonJS规范为JS指定了一个美好的愿景,希望JS能够在任何地方运行。
  • CommonJS对模块的定义十分简单:
    1. 模块引用
    2. 模块定义
    3. 模块标识

1、模块引用

在规范中,定义了require()方法,这个方法接手模块标识,以此将一个模块引入到当前运行环境中。
require()可以传递一个文件的路径作为参数,node将会自动根据该路径来引入外部模块,这里的路径,如果是使用的相对路径,必须以.或…开头。
使用require()引入模块以后,该函数会返回一个对象,这个对象代表的是引入的模块。

var math = require('./math');

2、模块定义

  • 在运行环境中,提供了exports对象用于导出当前模块的方法或者变量,并且它是唯 一的导出的出口。
  • 在模块中还存在一个module对象,它代表模块自身,而exports是module的属性
  • 在Node中一个文件就是一个模块。
  • 模块的定义十分简单,接口也十分简洁。 每个模块具有独立的空间,它们互不干扰,在引用时也显得干净利落。
exports.xxx = function() {
    
    };
module.exports = {
    
    };

3、模块标识

  • 模块标识其实就是模块的名字,也就是传递给require()方法的参数
  • 我们使用require()引入外部模块时,使用的就是模块标识,我们可以通过模块标识来找到指定的模块
    • 模块分成两大类
      • 核心模块(比如下面提到的文件模块fs,不用通过路径来引)
        • 由node引擎提供的模块
        • 核心模块的标识就是,模块的名字
      • 文件模块(比如02.module和math)
        • 由用户自己创建的模块
        • 文件模块的标识就是文件的路径(绝对路径,相对路径)相对路径使用.或…开头

代码示例

/*02.module.js*/
console.log("我是一个模块,我是02.module.js");
// 在Node中,每一个js文件中的js代码都是独立运行在一个函数中而不是全局作用域,所以一个模块的中的变量和函数在其他模块中无法访问
// 不用export的话,哪怕03中引入了02module,也是获取不到02中的变量和函数的
// var x = 10;
// var y = 20

// 我们可以通过 exports 来向外部暴露变量和方法。
// 只需要将需要暴露给外部的变量或方法设置为exports的属性即可*/
// 向外部暴露属性或方法
exports.x = "我是02.module.js中的x";
exports.y = "我是y";
exports.fn = function () {
    
    };

/* 模块 math
	add(a , b); 求两个数的和
	mul(a , b); 求两个数的积
*/
module.exports.add = function (a , b) {
    
    
	return a+b;
};

module.exports.mul = function (a , b) {
    
    
	return a*b;
};

/*03.module.js*/
// 引入模块
var md = require("./02.module");
var math = require("./math");
var fs = require("fs");

console.log(md);
console.log(math.add(123,456));
// console.log(fs);     

输出结果:
我是一个模块,我是02.module.js
{ x: ‘我是02.module.js中的x’, y: ‘我是y’, fn: [Function] }
579

4、全局变量

在node中有一个全局对象 global,它的作用和网页中window类似

  • 在全局中创建的变量都会作为global的属性保存
  • 在全局中创建的函数都会作为global的方法保存
var a = 10;
b = 10;   //这就是全局变量

console.log(global.a);  //输出结果是undefine说明a不是全局变量
console.log(global.b);  //输出结果是10

当node在执行模块中的代码时,所有代码会被如下这样一个函数包裹住
function (exports, require, module, __filename, __dirname) {}
(也就是说,node把我们所写的内容(模块中的代码)都是包装在一个函数function中执行的,并且在函数执行时,同时传递进了5个实参)

  • 1、exports
    • 该对象用来将变量或函数暴露到外部
  • 2、require
    - 函数,用来引入外部的模块
  • 3、module
    • module代表的是当前模块本身
    • exports就是module的属性
      • 注: 既可以使用 exports 导出,也可以使用module.exports导出,具体的区别之后详细提。
        console.log(exports);
        console.log(module.exports == exports); //是true
  • 4、 __filename
    • C:\Users\20151\WebstormProjects\learingnode\01.node\04.module.js
    • 当前模块的完整路径
  • 5、__dirname
    • C:\Users\20151\WebstormProjects\learingnode\01.node
    • 当前模块所在文件夹的完整路径

5、exports和module.exports

/*05.module.js模块*/
var hello = require("./helloModule");

console.log(hello.name);
console.log(hello.age);
hello.sayName();

/*helloModule.js模块*/
// exports.name = "孙悟空";
// exports.age = 18;
// exports.sayName = function () {
    
    
	// console.log("我是孙悟空~~~");
// };

// module.exports.name = "孙悟空";
// module.exports.age = 18;
// module.exports.sayName = function () {
    
    
    // console.log("我是孙悟空~~~");
// };
// 此时,以上两种方式都可以把变量和方法暴露出去的,05.module.js也都可以获取到。

// 但如果写成这样的=一个对象的形式,就只能使用module.exports,而exports不行。
module.exports  = {
    
    
	name:"猪八戒",
	age:28,
	sayName:function () {
    
    
		console.log("我是猪八戒");
	}
};

exports 和 module.exports的区别

  • exports是改变量。而不是改对象
    • 通过exports只能使用.的方式来向外暴露内部变量
      exports.xxx = xxx
  • module.exports是改对象。
    • 而module.exports既可以通过.的形式,也可以直接赋值
      module.exports.xxx = xxxx
      module.exports = {}

联想理解

// 基本数据类型
var a = 10;
var b = a;
a++;
console.log("a = "+a);   //a=11
console.log("b = "+b);   //b=10

在这里插入图片描述

// 引用数据类型
var obj = new Object();
obj.name = "孙悟空";
var obj2 = obj;
obj2.name = "猪八戒";   //改对象

obj2 = null;   // 改变量
console.log("obj = "+obj.name);
console.log("obj2 = "+obj2);

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_32755875/article/details/109499383