1. 环境
首先,我们来了解一下nodejs执行起来主要需要什么
- CommonJS
commonjs是nodejs所用的模块规范
- global对象
我们知道在浏览器中运行的JavaScript包含BOM、DOM,其中window就是一个全局对象,但是nodejs并没有BOM、DOM这些东西,所有也没有window这个全局对象,取而代之的是global,同样里面也有一些属性和方法供我们使用。
- process
代表当前执行的进程,挂在global下面
1.1 CommonJS
- 每个文件是一个模块,有自己的作用域
- 在模块内部module变量代表模块本身
- module.exports 属性代表模块对外的接口
为了理解以上内容,我们写这样一段代码
然后在命令行里运行一下,输入下面这行代码进入调试模式(--inspect进入调试模式,-brk在开始的时候停下)
接着我们打开chrome进入chrome://inspect
,回车后可以看到下面的界面
点击inspect就可以进入调试界面了
从图中我们可以看到,我们实际执行的代码在nodejs中运行的时候,被一个括号和一个分号包裹住,里面是一个function,这些都是nodejs内部帮我们做的(模块自己的作用域),这个function传入了5个变量,分别是
- exports
注意,不能直接将exports变量指向一个值,因为这样等于切断了exports与module.exports的联系。
下面的写法是无效的,因为exports不再指向module.exports了。
exports = function(x) {console.log(x)};
复制代码
下面的写法hello函数是无法对外输出的,因为module.exports被重新赋值了。
exports.hello = function() {
return 'hello';
};
module.exports = 'Hello world';`
复制代码
这意味着,如果一个模块的对外接口,就是一个单一的值,不能使用exports输出,只能使用module.exports输出。
- require
- module
- __filename
- __dirname
2. require
2.1 require规则
- /表示绝对路径,./表示相对于当前文件的
- 支持js、json、node扩展名,不写依次尝试
- 不写路径则认为是build-in模块或者各级node_modules内的第三方模块
2.2 require特性
- module 被加载的时候执行,加载后缓存
举个栗子,我们先写一个模块
这个模块导出一个变量num,并在开始的时候打印一个'hello'接着,我们在另一个文件里引入这个模块
运行这个文件 可以看到,我们加载了两次demo模块,而hello只打印了一次所以,module只有在第一次被加载的时候会执行
- 一旦出现某个模块被循环加载,就只输出已经执行的部分,还未执行的部分不会输出
这个定义有点难懂,不过没关系,我们还是通过例子来理解
我们先写三个js文件
然后我们执行main.js文件,执行步骤如下
-
首先引入了a.js文件,我们去加载a.js文件
-
在a.js中第一行将x赋值 'a1',接着引入了b.js,我们又去加载b.js文件
-
在b.js中第一行将x赋值 'b1',接着又去引入a.js文件,此时构成循环引用,因此只能引用a.js的部分内容,也就是
exports.x='a1'
,又将x赋值为'a1',因此首先打印出b.js a1
-
接着,a.js打印出来
a.js b2
,因为b.js的已经执行完毕了,所以引用到的x为b2 -
main.js文件中,由于a.js和b.js都已经执行完毕,所以打印出
main.js a2
,main.js b2
控制点最终打印
转载于:https://juejin.im/post/5d00a0336fb9a07ec27b9c3a