我正在从blog了解CommonJS,并且在代码方面遇到以下问题:
在这个例子中,我们基本上制作了两个模块副本:一个是 我们出口它,当我们需要它时。而且,副本中 main.js现在与原始模块断开连接。这就是原因 当我们递增计数器时它仍然返回1 - 因为计数器 我们导入的变量是计数器的断开连接的副本 来自模块的变量。
// lib/counter.js
var counter = 1;
function increment() {
counter++;
}
function decrement() {
counter--;
}
module.exports = {
counter: counter,
increment: increment,
decrement: decrement
};
// src/main.js
var counter = require('../../lib/counter');
counter.increment();
console.log(counter.counter); // 1
因此,如果创建了2个副本,那么每个副本都不会有自己的counter
和increment
版本吗?因此,每一个都将连接到他们自己的increment
函数?作者说,{。1}}中有counter
,increment
和decrement
的副本,而var counter = require('../../lib/counter')
中有另一个副本,所以不应该{ {1}}调用require副本中的counter.increment
函数,increment
返回require副本中的连接计数器?
答案 0 :(得分:1)
我认为该声明是为了实现ES6模块与nodejs CommonJS模块之间的对比。它并不完全正确。
当您需要模块时,您需要了解一些事项。
require
如何在幕后工作?
简而言之,调用require
所需的模块代码将被执行并缓存。
在执行模块代码之前,Node.js将使用函数包装器(module wrapping)来包装它。这可以确保顶级变量(如计数器)的范围限定为模块而不是全局对象。这意味着如果你正在导出一个要在另一个模块中使用的函数,它对于模块中声明的变量可以表现为closure。最后返回module.exports
的内容。
关于原始对象类型和对象类型如何进行值赋值?
让我们看看module.exports
的{{1}}
您将看到它正在导出原始值(lib/counter.js
)加上两个函数(counter
和increment
)。作为原始值的decrement
被其值复制,即数字1被设置为counter
的值,而增量和减量(都是第一类对象)被其引用复制。实际上,module.exports.counter
和module.exports.increment
都是关闭的在其正文中使用的module.exports.decrement
变量。
您可以在this帖子中阅读有关原始与对象分配的更多信息。
最后在counter
内main.js
变量(从计数器分配了module.exports的内容)是一个具有以下键的对象。
因此,您可以看到函数内部的计数器变量是指计数器模块中定义的那个。由于counter
值仅通过其值导出,因此对它的任何操作都不会影响原始模块变量