module.export和export之间有什么区别

时间:2017-04-13 16:51:24

标签: node.js

module.exportexport之间的区别是什么?

如果module.export对象中有一些属性怎么办? 那么export.xx会无效吗?

4 个答案:

答案 0 :(得分:4)

首先它是exportsmodule.exports而不是exportmodule.export(JavaScript中也有export个关键字,但不支持节点)。

每个节点模块都包含此功能:

(function (exports, require, module, __filename, __dirname) {
  // Your module code actually lives in here
});

请参阅:https://nodejs.org/api/modules.html#modules_the_module_wrapper

您的模块不会像某些人想的那样从该函数返回导出的对象。它只能通过向提供的参数添加属性将数据传递给调用者。

module.exportsexports 最初是同一个对象 - 但是module.exports 实际导出如果他们最终不是同一个对象。

这意味着这将是相同的:

module.exports.x = 1;
# or:
exports.x = 1;

因为它改变了同一个对象的属性

不会相同:

module.exports = {x: 1};

这样:

exports = {x: 1};

最后一个不会导出 x,因为它会替换 exports中的对象(原来相同对象为module.exports),同时将module.exports中的默认空对象保留为实际导出。

module.exports = {x: 1}; 也会替换一个新对象,但它会将其放在需要实际导出的位置。请注意changes the property对象的此module指令,调用程序在包含模块的隐式函数之后可以看到它。

现在这可行:

exports = {x: 1};
module.exports = exports;

因为它将exports中的对象替换为新的对象,但它也将其放入module.exports

请记住,如果你没有用新对象替换其中一个,那么它总是module.exports最重要,那么你可以在设置它们的属性时互换使用它们:

exports.x = 1;
module.exports.y = 2;

有关详细信息,请参阅此答案:

答案 1 :(得分:3)

模块是对象, exports 是模块对象的属性(变量)。

const module = { 
   //property
   exports: {} 
}; 

导出 module.exports 的快捷方式,直到为其分配新对象

  1. exports === module.exports

    module.exports.hello = true;
    exports.hello = true; 
    
  2. exports!== module.exports

    module.exports.hello = true;
    exports = { hello: true };
    

    exports 属性完全被新对象替换。

  3. Reference

    function require(/* ... */) {
       const module = { exports: {} };
       ((module, exports) => {
          // Your module code here. In this example, define a function.
          function someFunc() {}
          exports = someFunc;
          // At this point, exports is no longer a shortcut to 
          // module.exports, and
          // this module will still export an empty default object.
          module.exports = someFunc;
          // At this point, the module will now export someFunc, instead of 
          //the default object.
        })(module, module.exports);
       return module.exports;
     }
    

答案 2 :(得分:0)

module.exports实际上是require函数返回的内容,当您将脚本的路径传递给require函数时,您的代码将在函数表达式中包装并运行,该函数表达式具有名为{{的参数1}}这是一个空对象,然后exports将传递给它。通常它是module.exports的简写,换句话说,它是指向内存中同一个对象的两个变量,所以看起来很相似,对吧?

但实际上存在差异,module.exports在某些模式中表现不同,让我们举一个关于这类模式的例子,假设我们有一个名为tada.js的脚本:

exports

如果我在app.js中需要这个脚本:

exports = function(){
    console.log('Tada');
}

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

那么你期望看到什么?

嗯,这将是输出:

var tada = require('./tada');

它将console.log(exports); // [Function] console.log(module.exports); // {} 显示为函数,将exports显示为空对象。但是,正如我告诉你的那样,这两个只是两个指向内存中相同对象的变量,通过引用传递,所以它们不是假设具有相同的值吗?好吧,也许在任何其他语言中,它会像那样,但在JavaScript中,事情有点不同。

在JavaScript中,如果我们使用module.exports来分配值,它实际上会在内存中创建一个新对象,换句话说,在我们的示例中,=reference之间exports {1}}会破坏,这意味着module.exportsexports最初指向内存中的同一个对象,但是当我们这样做时:

module.exports

该引用已损坏且现在exports = function(){ console.log('Tada'); } 指向内存中的新对象。

还要记住,require函数只返回exports,而不是module.exports,这就是为什么我们在示例中为exports获取空对象的原因以及引用被破坏后{{1} },module.exports不再指向同一个对象。

要解决此问题,您需要module.exports而不是覆盖。因此,如果我们将示例更改为此,则exportsmutate将具有相同的值:

exports

答案 3 :(得分:0)

此示例将解释所有内容:

// page2.js

Select-String -Context x,y

// app.js

 exports = () => { console.log("Foo") };
 module.exports = () => { console.log("Bar") };