• nodejs中exports与module.exports的实践


    只要是在nodejs中写自己的文件模块就少不了会遇到module.exports和exports的使用,看别人的代码大多都会使用“module.exports=exports=<对象/函数等>”怪异的串联用法,一问原因,貌似都是云里雾里,如此写法更像是保守的防止性写法。

    这种问题除了看源代码外,只能写点代码进行求证。

    写了两个模块文件,provider.js产生任意类型的对象, customer.js返回并输出provider对象。

    第一种情况:

    provider.js,直接在exports上设置任意类型的对象。

    exports = {name:'kxh'}
    /*exports = function(){
      console.log('kxh');
    };
    exports = 'kxh';*/
    
    console.log('*******provider-module***********');
    console.log(module);
    console.log('*******provider-exports***********');
    console.log(exports);

    customer.js

    var p = require('./provider');
    
    console.log('*******customer-result***********');
    console.log(p);

    执行customer.js结果:

    *******provider-module***********
    { id: 'D:\ProgramDemos\Web\nodejs\TestNode\provider.js',
      exports: {},
      parent:
       { id: '.',
         exports: {},
         parent: null,
         filename: 'D:\ProgramDemos\Web\nodejs\TestNode\customer.js',
         loaded: false,
         children: [ [Circular] ],
         paths:
          [ 'D:\ProgramDemos\Web\nodejs\TestNode\node_modules',
            'D:\ProgramDemos\Web\nodejs\node_modules',
            'D:\ProgramDemos\Web\node_modules',
            'D:\ProgramDemos\node_modules',
            'D:\node_modules' ] },
      filename: 'D:\ProgramDemos\Web\nodejs\TestNode\provider.js',
      loaded: false,
      children: [],
      paths:
       [ 'D:\ProgramDemos\Web\nodejs\TestNode\node_modules',
         'D:\ProgramDemos\Web\nodejs\node_modules',
         'D:\ProgramDemos\Web\node_modules',
         'D:\ProgramDemos\node_modules',
         'D:\node_modules' ] }
    *******provider-exports***********
    { name: 'kxh' }
    *******customer-result***********
    {}

    从结果看,直接向exports上设置任意类型的对象都不会被require返回给调用模块。require返回的是module.exports的空对象。

    第二种情况:

    provider.js,为exports设置任意类型的属性。

    exports.name = {firstName:'xh', lastName:'k'};
    //exports.name = "kxh";
    /*exports.printName = function(){
      console.log("kxh");
    };*/
    
    console.log('*******provider-module***********');
    console.log(module);
    console.log('*******provider-exports***********');
    console.log(exports);

    customer.js不变。

    执行customer.js结果:

    *******provider-module***********
    { id: 'D:\ProgramDemos\Web\nodejs\TestNode\provider.js',
      exports: { name: { firstName: 'xh', lastName: 'k' } },
      parent:
       { id: '.',
         exports: {},
         parent: null,
         filename: 'D:\ProgramDemos\Web\nodejs\TestNode\customer.js',
         loaded: false,
         children: [ [Circular] ],
         paths:
          [ 'D:\ProgramDemos\Web\nodejs\TestNode\node_modules',
            'D:\ProgramDemos\Web\nodejs\node_modules',
            'D:\ProgramDemos\Web\node_modules',
            'D:\ProgramDemos\node_modules',
            'D:\node_modules' ] },
      filename: 'D:\ProgramDemos\Web\nodejs\TestNode\provider.js',
      loaded: false,
      children: [],
      paths:
       [ 'D:\ProgramDemos\Web\nodejs\TestNode\node_modules',
         'D:\ProgramDemos\Web\nodejs\node_modules',
         'D:\ProgramDemos\Web\node_modules',
         'D:\ProgramDemos\node_modules',
         'D:\node_modules' ] }
    *******provider-exports***********
    { name: { firstName: 'xh', lastName: 'k' } }
    *******customer-result***********
    { name: { firstName: 'xh', lastName: 'k' } }

    从结果看,为exports设置任意类型的属性,module.exports保持同步,能被require返回出去。

    第三种情况:

    provider.js,为exports设置任意类型的属性,并且为module.exports设置同名的或不同名的任意类型的属性。

    exports.name = {firstName:'xh', lastName:'k'};
    //exports.name = "kxh";
    /*exports.printName = function(){
      console.log("kxh");
    };*/
    //module.exports.name = {firstName:'wf', lastName:'z'};
    module.exports.mail = "kxh@kxh.com";
    
    console.log('*******provider-module***********');
    console.log(module);
    console.log('*******provider-exports***********');
    console.log(exports);

    customer.js不变。

    执行customer.js结果:

    *******provider-module***********
    { id: 'D:\ProgramDemos\Web\nodejs\TestNode\provider.js',
      exports:
       { name: { firstName: 'xh', lastName: 'k' },
         mail: 'kxh@kxh.com' },
      parent:
       { id: '.',
         exports: {},
         parent: null,
         filename: 'D:\ProgramDemos\Web\nodejs\TestNode\customer.js',
         loaded: false,
         children: [ [Circular] ],
         paths:
          [ 'D:\ProgramDemos\Web\nodejs\TestNode\node_modules',
            'D:\ProgramDemos\Web\nodejs\node_modules',
            'D:\ProgramDemos\Web\node_modules',
            'D:\ProgramDemos\node_modules',
            'D:\node_modules' ] },
      filename: 'D:\ProgramDemos\Web\nodejs\TestNode\provider.js',
      loaded: false,
      children: [],
      paths:
       [ 'D:\ProgramDemos\Web\nodejs\TestNode\node_modules',
         'D:\ProgramDemos\Web\nodejs\node_modules',
         'D:\ProgramDemos\Web\node_modules',
         'D:\ProgramDemos\node_modules',
         'D:\node_modules' ] }
    *******provider-exports***********
    { name: { firstName: 'xh', lastName: 'k' },
      mail: 'kxh@kxh.com' }
    *******customer-result***********
    { name: { firstName: 'xh', lastName: 'k' },
      mail: 'kxh@kxh.com' }

    从结果看,如果设置不同名的属性,则为合并到module.exports并返回,如果是同名属性则require返回的全是module.exports。

    第四种情况:

    provider.js,不论为exports设置社么样类型的属性,直接为module.exports设置了任意类型对象。

    exports.name = {firstName:'xh', lastName:'k'};
    //exports.name = "kxh";
    /*exports.printName = function(){
      console.log("kxh");
    };*/
    
    //module.exports = {name:'kxh'};
    module.exports = function(){
      console.log('kxh');
    };
    
    console.log('*******provider-module***********');
    console.log(module);
    console.log('*******provider-exports***********');
    console.log(exports);

    customer.js不变。

    执行customer.js结果:

    *******provider-module***********
    { id: 'D:\ProgramDemos\Web\nodejs\TestNode\provider.js',
      exports: [Function],
      parent:
       { id: '.',
         exports: {},
         parent: null,
         filename: 'D:\ProgramDemos\Web\nodejs\TestNode\customer.js',
         loaded: false,
         children: [ [Circular] ],
         paths:
          [ 'D:\ProgramDemos\Web\nodejs\TestNode\node_modules',
            'D:\ProgramDemos\Web\nodejs\node_modules',
            'D:\ProgramDemos\Web\node_modules',
            'D:\ProgramDemos\node_modules',
            'D:\node_modules' ] },
      filename: 'D:\ProgramDemos\Web\nodejs\TestNode\provider.js',
      loaded: false,
      children: [],
      paths:
       [ 'D:\ProgramDemos\Web\nodejs\TestNode\node_modules',
         'D:\ProgramDemos\Web\nodejs\node_modules',
         'D:\ProgramDemos\Web\node_modules',
         'D:\ProgramDemos\node_modules',
         'D:\node_modules' ] }
    *******provider-exports***********
    { name: { firstName: 'xh', lastName: 'k' } }
    *******customer-result***********
    [Function]

    从结果看,不论为exports设置社么样类型的属性,直接为module.exports设置了任意类型对象,则require一律返回module.exports。

    从上面的四种实践结果来看:

    require返回的是module.exports,在module.exports上可以设置函数、对象实例、基本类型的变量等,因此,一般就是module.exports作为模块的到处就行了。

    如果想用exports作为模块的返回,那么就为它设置一个属性,并且不要在module.exports上设置同名的属性。

    end

    ^-^

  • 相关阅读:
    处理视频流时可能出现的重复帧问题及解决办法
    shell脚本中cd命令无效
    C++教程之初识编程
    若干排序算法的Python实现方法及原理
    C/C++反三角函数使用注意
    ubuntu下安装pip install mysqlclient 报错 command "python setup.py egg_info" failed with error.....解决方案
    使用scrapy框架的monkey出现monkeypatchwarning: monkey-patching ssl after ssl...的解决办法
    机器学习之利用KNN近邻算法预测数据
    python数据分析的工具环境
    python代码实现经典排序算法
  • 原文地址:https://www.cnblogs.com/kongxianghai/p/3936197.html
Copyright © 2020-2023  润新知