在这个页面上( http://docs.nodejitsu.com/articles/getting-started/what-is-require ),它指出,“如果你想设置的出口对象函数或一个新的对象,你必须使用module.exports对象。”
我的问题是为什么。
// right
module.exports = function () {
console.log("hello world")
}
// wrong
exports = function () {
console.log("hello world")
}
我console.logged结果( result=require(example.js)
和第一个是[Function]
第二个是{}
能否请您解释一下它背后的原因是什么? 我在这里读的帖子: module.exports VS在Node.js的出口 。 这是有帮助的,但没有解释为什么它的设计以这种方式的原因。 会不会有问题,如果出口的参照直接返回?
module
是具有一个普通的JavaScript对象exports
属性。 exports
是一个普通的JavaScript变量,恰好被设置为module.exports
。 在你的文件的末尾,Node.js的基本上会“回归” module.exports
到require
的功能。 以查看节点JS文件用简单的方式可以是这样的:
var module = { exports: {} };
var exports = module.exports;
// your code
return module.exports;
如果您在设置属性exports
,像exports.a = 9;
,将设置module.exports.a
以及因为对象是通过周围如在JavaScript中,这意味着,如果您设置多个变量同一个对象,他们都是同一个对象的引用; 所以后来exports
和module.exports
是同一个对象。
但是,如果你设置exports
新的东西,它将不再被设为module.exports
,因此exports
和module.exports
不再是同一个对象。
蕾妮的答案是很好的解释。 除了用一个例子回答:
节点做了很多事情,以你的文件和重要的一个包裹文件。 里面的NodeJS源代码“module.exports”返回。 让我们退后一步,了解包装。 假设你有
greet.js
var greet = function () {
console.log('Hello World');
};
module.exports = greet;
上面的代码被包装为IIFE(立即调用函数表达式)的NodeJS源代码内,如下所示:
(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
和上述函数被调用(。适用())和返回module.exports。 这时module.exports和出口指向相同的参考。
现在,想象你重新写greet.js作为
exports = function () {
console.log('Hello World');
};
console.log(exports);
console.log(module.exports);
输出将是
[Function]
{}
其原因是:module.exports是一个空对象。 我们没有设置任何东西module.exports而我们设定出口=()函数.....在新greet.js。 所以,module.exports是空的。
技术上出口和module.exports应指向相同的参考(这就是正确的!)。 但是,我们分配功能()的时候....出口,这会在内存另一个对象使用“=”。 所以,module.exports和出口产生不同的结果。 当涉及到出口,我们不能忽略它。
现在,想象你重新写(这被称为突变)greet.js(指蕾妮回答)作为
exports.a = function() {
console.log("Hello");
}
console.log(exports);
console.log(module.exports);
输出将是
{ a: [Function] }
{ a: [Function] }
正如你所看到module.exports和出口都指向这是一个功能相同的参考。 如果设置了出口,然后它会在,因为JS module.exports可以设置一个属性,对象是按引用传递。
结论总是使用module.exports以避免混淆。 希望这可以帮助。 编码愉快:)
此外,一个东西,可能有助于了解:
math.js
this.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
因此,在默认情况下,“本”实际上是等于module.exports。
但是,如果你改变你的实现:
math.js
var add = function (a, b) {
return a + b;
};
module.exports = {
add: add
};
在这种情况下,它会正常工作,但是,“这种”不等于不再module.exports,因为一个新的对象被创建。
console.log(this === module.exports); // false
console.log(this === exports); // true
console.log(module.exports === exports); // false
而现在,什么会被要求返回的是什么的module.exports中定义的,不是这个或出口了。
另一种方式来做到这一点是:
math.js
module.exports.add = function (a, b) {
return a + b;
};
要么:
math.js
exports.add = function (a, b) {
return a + b;
};
刘若英的约之间的关系答案exports
和module.exports
是很清楚的,它是所有关于JavaScript的引用。 只是想补充一点:
我们认为,这在许多节点模块:
var app = exports = module.exports = {};
这将确保即使我们改变module.exports,我们仍然可以通过使这两个变量指向同一对象使用的出口。
文章来源: Difference between “module.exports” and “exports” in the CommonJs Module System