美文网首页
node.js中module.exports vs export

node.js中module.exports vs export

作者: 涅槃快乐是金 | 来源:发表于2024-04-07 15:19 被阅读0次

    如果你有过 Node.js的开发经验,你可能熟悉用于将代码从一个模块导出到另一个模块的module.exportsexports关键字。虽然它们乍一看似乎可以互换使用,但有充分的理由选择其中之一。

    导入导出模式

    让我们先来看一下 Node.js中几种常见的 CommonJS导入导出模式。

    修改 module.exports 属性

    // math.js
    const add = (a, b) => {
      return a + b;
    };
    
    const subtract = (a, b) => {
      return a - b;
    };
    
    module.exports.add = add;
    module.exports.subtract = subtract;
    
    //index.js
    const math = require("./math");
    
    console.log(math.add(2, 3)); // 5
    console.log(math.subtract(2, 3)); // -1
    

    在第一种模式中,函数附加到module.exports 对象的属性上。我们可以在 index.js中看到正确的值被记录。

    修改 exports 属性

    // math.js
    const add = (a, b) => {
      return a + b;
    };
    
    const subtract = (a, b) => {
      return a - b;
    };
    
    exports.add = add;
    exports.subtract = subtract;
    
    //index.js
    const math = require("./math");
    
    console.log(math.add(2, 3)); // 5
    console.log(math.subtract(2, 3)); // -1
    

    在第二种模式中,你将函数附加到exports对象的属性上。在 index.js中仍然记录了正确的值。

    现在,这引出了一个问题:当exports看起来可以用更少的按键来实现相同的结果时,为什么要使用 module.exports 呢?为了回答这个问题,让我们看一下以下两种模式。

    module.exports分配新对象

    // math.js
    const add = (a, b) => {
      return a + b;
    };
    
    const subtract = (a, b) => {
      return a - b;
    };
    
    module.exports = {
      add,
      subtract,
    };
    
    //index.js
    const math = require("./math");
    
    console.log(math.add(2, 3)); // 5
    console.log(math.subtract(2, 3)); // -1
    

    在第三种模式中,将一个新对象分配给 module.exports。然后在index.js中记录了正确的值。

    给 exports 分配新对象

    // math.js
    const add = (a, b) => {
      return a + b;
    };
    
    const subtract = (a, b) => {
      return a - b;
    };
    
    exports = {
      add,
      subtract,
    };
    
    //index.js
    const math = require("./math");
    
    console.log(math.add(2, 3)); // TypeError: math.add is not a function
    console.log(math.subtract(2, 3)); // TypeError: math.subtract is not a function
    console.log(math); // {}
    

    在第四种模式中,将一个新对象分配给 exports。然而,这种模式似乎不起作用,因为 math看起来是一个空对象。让我们了解一下为什么。

    JavaScript 中的对象引用

    让我们重新思考一下 JavaScript 中的对象引用是如何工作的。当你将一个对象分配给另一个对象时,两个对象都指向同一个内存地址。修改一个对象也会修改另一个对象。让我们看看这个例子。

    const superhero1 = {
      name: "Bruce Wayne",
    };
    
    const superhero2 = superhero1; // 创建对 superhero1 的引用
    
    superhero2.name = "Clark Kent"; // 修改 superhero2 的名字
    
    console.log(superhero1); // { name: 'Clark Kent' } superhero1 的名字被更新了
    

    在这个例子中,superhero1superhero2都引用同一个superhero。修改 superhero2 也会修改superhero1

    然而,分配一个新对象会破坏引用。

    const superhero1 = {
      name: "Bruce Wayne",
    };
    
    let superhero2 = superhero1; // 创建对 superhero1 的引用
    
    superhero2 = { name: "Clark Kent" }; // 分配会破坏引用
    
    superhero2.name = "Barry Allen"; // 只有 superhero2 被修改
    
    console.log(superhero1); // { name: 'Bruce Wayne' } superhero1 没有受到影响
    

    在这种情况下,分配会破坏引用,修改 superhero2不再影响 superHero1

    module.exports vs. exports

    现在我们了解了 JavaScript中对象的工作原理,让我们将其与 module.exportsexports 相关联起来。在Node.js中,module是一个普通的 JavaScript对象,具有一个exports属性。exports是一个普通的JavaScript变量,恰好被设置为module.exports。当你在另一个文件中 require一个模块时,该模块内的代码被执行,并且只返回 module.exports

    var module = { exports: {} };
    
    var exports = module.exports;
    
    // 通过对象引用将 exports 分配给 module.exports...
    
    exports.add = add; // ...导致 module.exports.add = add
    exports.subtract = subtract; // ...导致 module.exports.subtract = subtract
    
    // module.exports 对象包含 add 和 subtract 属性
    
    return module.exports;
    

    然而,如果你将一个新对象分配给exports,引用将被破坏,更新exports将不再更新 module.exports

    var module = { exports: {} };
    
    var exports = module.exports;
    
    // 以下分配会破坏对象引用
    
    exports = {
      add: (a, b) => a + b,
      subtract: (a, b) => a - b,
    };
    
    return module.exports; // module.exports = {}
    

    如果你尝试访问导出对象上的addsubtract,将会抛出错误,因为 module.exports是空的。因此,虽然在第一个导入导出模式中 module.exportsexports看起来可以互换使用,但它们并不相同。

    结论

    什么时候应该选择 exports而不是 module.exports?简短的答案是你可能不应该这样做。虽然 exports可能更短,看起来更方便,但它可能会引起混淆,这是不值得的。请记住,exports 只是对 module.exports的引用,将一个新对象分配给 exports会破坏该引用。

    相关文章

      网友评论

          本文标题:node.js中module.exports vs export

          本文链接:https://www.haomeiwen.com/subject/lyttxjtx.html