提问者:小点点

CommonJs模块系统中Module.Exports和Exports的区别


在这个页面(http://docs.nodejitsu.com/articles/getting-started/what-is-require)中,它指出“如果您想将exports对象设置为函数或新对象,您必须使用Module.exports对象。”

我的问题是为什么。

// right
module.exports = function () {
  console.log("hello world")
}
// wrong
exports = function () {
  console.log("hello world")
}

I console.log结果(codeResult=require(example.js)/code>),第一个是,第二个是

请您解释一下背后的原因好吗?我在这里读了这篇文章:module.exports vs exports in node.js。它是有帮助的,但没有解释为什么它是那样设计的原因。出口的参考直接退回会不会有问题?


共3个答案

匿名用户

null

var module = { exports: {} };
var exports = module.exports;

// your code

return module.exports;

如果您在上设置一个属性,比如,那么它也会设置,因为对象在JavaScript中是作为引用传递的,这意味着如果您为同一个对象设置多个变量,那么它们都是同一个对象;因此是同一个对象。br>但是如果将设置为新对象,则它将不再设置为,因此不再是同一个对象。

匿名用户

Reneee的回答很好地解释了。给答案加上一个例子:

节点对您的文件做了很多事情,其中一个重要的是包装您的文件。在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指向相同的引用。

现在,假设您将greet.js重新编写为

exports = function () {
   console.log('Hello World');
};
console.log(exports);
console.log(module.exports);

输出将为

[Function]
{}

原因是:Module.Exports是一个空对象。我们没有为Module.exports设置任何内容,而是设置exports=function()....在新的greet.js中。因此,Module.Exports为空。

从技术上讲,exports和module.exports应该指向相同的引用(这是正确的)。但我们在分配函数()...时使用“=”。导出,它将在内存中创建另一个对象。所以,module.exports和exports产生了不同的结果。当涉及出口时,我们不能推翻它。

现在,假设您重新编写(这称为突变)greet.js(指Renee答案)为

exports.a = function() {
    console.log("Hello");
}

console.log(exports);
console.log(module.exports);

输出将为

{ a: [Function] }
{ a: [Function] }

如您所见,module.exports和exports指向相同的引用,这是一个函数。如果您在exports上设置一个属性,那么它将在module.exports上设置,因为在JS中,对象是通过引用传递的。

结论是始终使用module.exports以避免混淆。希望这能帮上忙。快乐编码:)

匿名用户

还有一件事可能有助于理解:

null

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

因此,默认情况下,“this”实际上等于module.exports。

但是,如果将实现更改为:

null

var add = function (a, b) {
    return a + b;
};

module.exports = {
    add: add
};

在这种情况下,它将正常工作,但是,“this”不再等于Module.Exports,因为创建了一个新对象。

console.log(this === module.exports); // false
console.log(this === exports); // true
console.log(module.exports === exports); // false

现在,require返回的是模块内部定义的。exports,而不是this或exports。

另一种方法是:

null

module.exports.add = function (a, b) {
    return a + b;
};

或者:

Math.js

exports.add = function (a, b) {
    return a + b;
};