Javascript 区别于;“出口”模块;及;“出口”;在CommonJs模块系统中
在此页()上,它声明“如果要将exports对象设置为函数或新对象,则必须使用module.exports对象。” 我的问题是为什么Javascript 区别于;“出口”模块;及;“出口”;在CommonJs模块系统中,javascript,node.js,commonjs,Javascript,Node.js,Commonjs,在此页()上,它声明“如果要将exports对象设置为函数或新对象,则必须使用module.exports对象。” 我的问题是为什么 // right module.exports = function () { console.log("hello world") } // wrong exports = function () { console.log("hello world") } I console.log记录结果(result=re
// right
module.exports = function () {
console.log("hello world")
}
// wrong
exports = function () {
console.log("hello world")
}
I console.log记录结果(result=require(example.js)
),第一个是[Function]
,第二个是{}
你能解释一下背后的原因吗?我在这里读了帖子:。这是有帮助的,但没有解释为什么它是这样设计的。如果直接返回导出的引用,是否会出现问题?
模块
是一个带有导出
属性的普通JavaScript对象exports
是一个普通JavaScript变量,恰好设置为module.exports
。
在文件末尾,node.js基本上会“返回”模块。将导出到require
函数。在节点中查看JS文件的简化方法如下:
var module = { exports: {} };
var exports = module.exports;
// your code
return module.exports;
如果在exports
上设置属性,如exports.a=9
,这将设置模块.exports.a
,因为对象在JavaScript中作为引用传递,这意味着如果您将多个变量设置为同一个对象,那么它们都是同一个对象;因此,导出
和模块。导出
是同一个对象。但是如果将
导出
设置为新的对象,它将不再设置为模块。导出
,因此导出
和模块。导出
不再是同一个对象。模块
是一个具有导出
属性的普通JavaScript对象exports
是一个普通JavaScript变量,恰好设置为module.exports
。
在文件末尾,node.js基本上会“返回”模块。将导出到require
函数。在节点中查看JS文件的简化方法如下:
var module = { exports: {} };
var exports = module.exports;
// your code
return module.exports;
如果在exports
上设置属性,如exports.a=9
,这将设置模块.exports.a
,因为对象在JavaScript中作为引用传递,这意味着如果您将多个变量设置为同一个对象,那么它们都是同一个对象;因此,导出
和模块。导出
是同一个对象。但是如果您将
导出
设置为新对象,它将不再设置为模块。导出
,因此导出
和模块。导出
不再是同一个对象。Rene关于导出
和模块。导出
之间关系的回答非常清楚,这都是关于javascript引用的。我只想补充一点:
我们可以在许多节点模块中看到这一点:
var-app=exports=module.exports={}代码>
这将确保即使我们更改了module.exports,我们仍然可以通过使这两个变量指向同一个对象来使用exports。Rene关于exports
和module.exports
之间关系的回答非常清楚,都是关于javascript引用的。我只想补充一点:
我们可以在许多节点模块中看到这一点:
var-app=exports=module.exports={}代码>
这将确保即使我们更改了module.exports,我们仍然可以通过使这两个变量指向同一个对象来使用exports。还有一点可以帮助理解:
math.js
this.add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
module.exports.add = function (a, b) {
return a + b;
};
exports.add = function (a, b) {
return a + b;
};
client.js
var math = require('./math');
console.log(math.add(2,2); // 4;
很好,在这种情况下:
console.log(this === module.exports); // true
console.log(this === exports); // true
console.log(module.exports === exports); // true
因此,默认情况下,“this”实际上等于module.exports
但是,如果将实现更改为:
math.js
this.add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
module.exports.add = function (a, b) {
return a + b;
};
exports.add = function (a, b) {
return a + b;
};
在这种情况下,它可以正常工作,但是,“this”不再等于module.exports,因为创建了一个新对象
console.log(this === module.exports); // false
console.log(this === exports); // true
console.log(module.exports === exports); // false
现在,require返回的是module.exports中定义的内容,不再是this或exports
另一种方法是:
math.js
this.add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
module.exports.add = function (a, b) {
return a + b;
};
exports.add = function (a, b) {
return a + b;
};
或:
math.js
this.add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
module.exports.add = function (a, b) {
return a + b;
};
exports.add = function (a, b) {
return a + b;
};
还有一件事可能有助于理解:
math.js
this.add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
module.exports.add = function (a, b) {
return a + b;
};
exports.add = function (a, b) {
return a + b;
};
client.js
var math = require('./math');
console.log(math.add(2,2); // 4;
很好,在这种情况下:
console.log(this === module.exports); // true
console.log(this === exports); // true
console.log(module.exports === exports); // true
因此,默认情况下,“this”实际上等于module.exports
但是,如果将实现更改为:
math.js
this.add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
module.exports.add = function (a, b) {
return a + b;
};
exports.add = function (a, b) {
return a + b;
};
在这种情况下,它可以正常工作,但是,“this”不再等于module.exports,因为创建了一个新对象
console.log(this === module.exports); // false
console.log(this === exports); // true
console.log(module.exports === exports); // false
现在,require返回的是module.exports中定义的内容,不再是this或exports
另一种方法是:
math.js
this.add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
module.exports.add = function (a, b) {
return a + b;
};
exports.add = function (a, b) {
return a + b;
};
或:
math.js
this.add = function (a, b) {
return a + b;
};
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
module.exports.add = function (a, b) {
return a + b;
};
exports.add = function (a, b) {
return a + b;
};
蕾妮的答案解释得很好。用一个例子补充答案:
节点对您的文件执行很多操作,其中一个重要的操作是包装您的文件。在nodejs内部返回源代码“module.exports”。让我们后退一步,了解包装器。假设你有
greet.js
var greet = function () {
console.log('Hello World');
};
module.exports = greet;
上述代码在nodejs源代码中包装为IIFE(立即调用的函数表达式),如下所示:
(function (exports, require, module, __filename, __dirname) { //add by node
var greet = function () {
console.log('Hello World');
};
module.exports = greet;
}).apply(); //add by node
return module.exports; //add by node
调用上述函数(.apply())并返回module.exports。
此时,module.exports和exports指向同一引用
现在,想象你在写
将.js作为
exports = function () {
console.log('Hello World');
};
console.log(exports);
console.log(module.exports);
输出将是
[Function]
{}
原因是:module.exports是空对象。我们没有将任何内容设置为module.exports,而是设置exports=function()。。。。。在new greet.js中。因此,module.exports为空
技术上,导出和module.exports应该指向相同的引用(这是正确的!!)。但是我们在赋值函数()时使用“=”。。。。导出,这将在内存中创建另一个对象。因此,module.exports和exports产生不同的结果。说到出口,我们不能忽略它
现在,想象你重新编写(这称为变异)
greet.js(指Renee answer)作为
输出将是
{ a: [Function] }
{ a: [Function] }
如您所见,module.exports和exports指向相同的位置