为什么在 a.js 中看不到 b.js 中定义的变量,尽管包括前者?
Why can't I see a variable defined in b.js within a.js, despite including the former?
这是b.js
var something = "hooorraaaaay!!!";
这是a.js
require( './b.js' );
console.log(something);
为什么 something
在 a.js
中没有被识别。我知道它是用 var
声明的,但我的理解是任何在函数外声明的变量都应该是全局变量。那为什么这不起作用?
让我假设您正在使用 node.js
从 require 函数判断。
node.js 将每个文件包装在其自己的范围内。这与 var
关键字的使用无关。 node.js 中的每个文件都称为一个模块。
现在假设你想包含一个模块,require
,你用对了。
但是因为你的模块不导出任何东西,当它被包含在其他模块中时它是无用的。
因此,在 b.js 文件的末尾,添加以下行:
module.exports.something = something;
现在我们终于可以使用导出的变量了:
var b = require('./b.js');
console.log('Something is : ' + b.something);
每个节点模块都在自己的范围内。默认情况下,模块 a
中的任何内容对模块 b
都是可见的。在模块上执行 require()
与包含源代码不同。它加载文件运行代码,然后外界唯一可用的是:
- 通过分配给
module.exports
. 从模块中显式导出的任何函数或属性
- 明确分配给节点中
global
对象的任何函数或属性。
所以,如果你想让 b.js
中的东西暴露给外界,你可以这样做:
// b.js
module.exports.callMe = function() {
console.log("I'm in module b");
}
然后,在 a.js
中,您可以这样做:
// a.js
var b = require('./b.js');
b.callMe();
这就是模块系统在 node.js 中的工作方式。它与仅在浏览器网页中包含 <script>
标记有很大不同。您可以在这些参考资料中阅读有关模块系统的更多信息:
Understanding module.exports and exports in Node.js
What is the purpose of Node.js module.exports and how do you use it?
Node.js Handbook - How require()
Actually Works
在内部,node.js 加载模块代码,然后将其插入到包装函数中。因此,节点模块中的每个顶级变量实际上只是该模块函数中的局部变量。这就是默认情况下没有全局声明或共享任何内容的原因。这是故意这样做的,这样每个模块都有自己的私有区域来存储它的状态,并且默认情况下不会干扰任何其他模块的变量。
然后您只显式导出要创建 public 的 property/function 接口,即便如此,它们仍然不会导出为 public 符号,因此它们不会与任何内容发生冲突否则。
所以,上面的 b.js 代码实际上在 node.js 运行时变成了这个:
(function (exports, module, require, __filename, __dirname){
module.exports.callMe = function() {
console.log("I'm in module b");
}
})(...);
(...)
包含传递给模块的实际变量。
这是b.js
var something = "hooorraaaaay!!!";
这是a.js
require( './b.js' );
console.log(something);
为什么 something
在 a.js
中没有被识别。我知道它是用 var
声明的,但我的理解是任何在函数外声明的变量都应该是全局变量。那为什么这不起作用?
让我假设您正在使用 node.js
从 require 函数判断。
node.js 将每个文件包装在其自己的范围内。这与 var
关键字的使用无关。 node.js 中的每个文件都称为一个模块。
现在假设你想包含一个模块,require
,你用对了。
但是因为你的模块不导出任何东西,当它被包含在其他模块中时它是无用的。
因此,在 b.js 文件的末尾,添加以下行:
module.exports.something = something;
现在我们终于可以使用导出的变量了:
var b = require('./b.js');
console.log('Something is : ' + b.something);
每个节点模块都在自己的范围内。默认情况下,模块 a
中的任何内容对模块 b
都是可见的。在模块上执行 require()
与包含源代码不同。它加载文件运行代码,然后外界唯一可用的是:
- 通过分配给
module.exports
. 从模块中显式导出的任何函数或属性
- 明确分配给节点中
global
对象的任何函数或属性。
所以,如果你想让 b.js
中的东西暴露给外界,你可以这样做:
// b.js
module.exports.callMe = function() {
console.log("I'm in module b");
}
然后,在 a.js
中,您可以这样做:
// a.js
var b = require('./b.js');
b.callMe();
这就是模块系统在 node.js 中的工作方式。它与仅在浏览器网页中包含 <script>
标记有很大不同。您可以在这些参考资料中阅读有关模块系统的更多信息:
Understanding module.exports and exports in Node.js
What is the purpose of Node.js module.exports and how do you use it?
Node.js Handbook - How require()
Actually Works
在内部,node.js 加载模块代码,然后将其插入到包装函数中。因此,节点模块中的每个顶级变量实际上只是该模块函数中的局部变量。这就是默认情况下没有全局声明或共享任何内容的原因。这是故意这样做的,这样每个模块都有自己的私有区域来存储它的状态,并且默认情况下不会干扰任何其他模块的变量。
然后您只显式导出要创建 public 的 property/function 接口,即便如此,它们仍然不会导出为 public 符号,因此它们不会与任何内容发生冲突否则。
所以,上面的 b.js 代码实际上在 node.js 运行时变成了这个:
(function (exports, module, require, __filename, __dirname){
module.exports.callMe = function() {
console.log("I'm in module b");
}
})(...);
(...)
包含传递给模块的实际变量。