美文网首页
module.exports和exports

module.exports和exports

作者: PoWerfulHeart | 来源:发表于2022-02-17 18:32 被阅读0次

    两者的关系

    exports = module.exports = {}

    nodejs如何导出模块

    当不改变module.exports和exports的指向,module.exports和exports均可导出,因为上面也说过这两个对象实际上指向的都是同一个堆地址

    不改变指向

      //a.js
      exports.a = 1;
      module.exports.b = 2;
      
      //b.js
      const test = require('./a');
      console.log(test);
      //output: { a: 1, b: 2 }
    

    改变指向:仅module.exports可导出

      //a.js
      exports.a = 1;   // exports = { a: 1 };
      module.exports = { b: 2 };
      
      //b.js
      const test = require('./a');
      console.log(test);
      //output: { b: 2 }
    

    刨根问底

    为什么指向一旦被改变exports就不能导出对象了呢?

    首先node加载模块的时候会用一个函数将代码包裹

      (function (exports, require, module, __filename, __dirname) {
      });
    

    当加载模块的时候,module已经被当作参数传入,所以即使module.exports的值改变也能够在其他文件中进行调用,也就是为什么指向一旦被改变,只有module.exports可导出。
    那么有同学问了exports也被当作参数传入啦~~~

    另外node(commonjs)加载模块时,其实是进行的一个浅拷贝(基本类型一样,引用类型拷贝地址),所以单独改变模块里面的变量值(非引用类型),并不会影响导入的值,而es6的import则是创建一个动态的只读引用,等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。

    利用node-inspector调试我们可以找到答案

      Module.prototype._compile = function(content, filename) {
      ......
      let result;
      //这里传入的exports其实是this.exports,而当前this是指向module的,所以加载模块传入的exports其实是module.exports,所以一旦改变了exports指向,就不能通过exports导出了
      const exports = this.exports;
      const thisValue = exports;
      const module = this;
      if (requireDepth === 0) statCache = new SafeMap();
      if (inspectorWrapper) {
        result = inspectorWrapper(compiledWrapper, thisValue, exports,
                                  require, module, filename, dirname);
      } else {
        result = ReflectApply(compiledWrapper, thisValue,
                              [exports, require, module, filename, dirname]);
      }
      hasLoadedAnyUserCJSModule = true;
      if (requireDepth === 0) statCache = null;
      return result;
    };
    

    相关文章

      网友评论

          本文标题:module.exports和exports

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