-->

在CommonJS的模块系统“module.exports”和“出口”的区别(Difference

2019-09-02 00:32发布

在这个页面上( 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的出口 。 这是有帮助的,但没有解释为什么它的设计以这种方式的原因。 会不会有问题,如果出口的参照直接返回?

Answer 1:

module是具有一个普通的JavaScript对象exports属性。 exports是一个普通的JavaScript变量,恰好被设置为module.exports 。 在你的文件的末尾,Node.js的基本上会“回归” module.exportsrequire的功能。 以查看节点JS文件用简单的方式可以是这样的:

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

// your code

return module.exports;

如果您在设置属性exports ,像exports.a = 9; ,将设置module.exports.a以及因为对象是通过周围如在JavaScript中,这意味着,如果您设置多个变量同一个对象,他们都是同一个对象的引用; 所以后来exportsmodule.exports是同一个对象。
但是,如果你设置exports新的东西,它将不再被设为module.exports ,因此exportsmodule.exports不再是同一个对象。



Answer 2:

蕾妮的答案是很好的解释。 除了用一个例子回答:

节点做了很多事情,以你的文件和重要的一个包裹文件。 里面的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以避免混淆。 希望这可以帮助。 编码愉快:)



Answer 3:

此外,一个东西,可能有助于了解:

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;
};


Answer 4:

刘若英的约之间的关系答案exportsmodule.exports是很清楚的,它是所有关于JavaScript的引用。 只是想补充一点:

我们认为,这在许多节点模块:

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

这将确保即使我们改变module.exports,我们仍然可以通过使这两个变量指向同一对象使用的出口。



文章来源: Difference between “module.exports” and “exports” in the CommonJs Module System