Node中exports与module.export的使用与区别

module.exports与exports的介绍

module.exports与exports都是将函数或者是方法暴露出去,require的时候进行调用,但是2者是有区别的。以下是代码:

复制代码
//ex.js

exports='danhuangmode';


//mex.js

  module.exports='danhuangmode';

//call_ex_mex.js

  var ex=require('./ex');
  var mex=require('./mex');

  console.log(ex);
  console.log('\n');
  console.log(mex);

复制代码

执行结果:

引用exports提供方法,输出是为一个对象,引用module.exports提供方法,输出为字符串。

exports内部提供接口,在外部引用时之间的关系如何?

exports内部处理暴露方法,是如何处理的,看如下代码:

复制代码
var string='this is in exports.js';

 function ex_fn () {
     console.log('this in funtion ex_fn');
}

var exobj={
    str1:"str1 exobj",
    exobjfn: function  () {
        console.log("in function");
    }
};

exports.string=string;
exports.ex_fn=ex_fn;
exports.exobj=exobj;
exports=exobj;
复制代码

调用代码:

复制代码
var ex=require('./ex');


console.log(ex.string);
console.log(ex.ex_fn);
console.log(ex.exobj);
console.log(ex);
复制代码

结果显示:

 

exports提供的所有接口,直接调用导出实例化的接口对象,会显示接口对象中所有提供的类型、函数、对象以及对象中的方法和对象。

module.exports对外提供接口如何处理?

复制代码

//mex.js

var ex_fn= function () {
     console.log('this in funtion ex_fn');
}

module.exports=ex_fn;

复制代码

调用代码mex.js:

复制代码
//引用mex.js

var ex=require('./mex');
ex();
console.log(ex);

 
复制代码

执行结果为:

 

 直接将函数作为返回。

再看下面一个例子:

复制代码
var person={
    name :"person's name",
    age :20,
    getAge: function  () {
        return this.age;
    }
}

module.exports = person;
复制代码

调用的代码:

复制代码
var person=require('./modulex');

console.log(person.name);
console.log(person.age);
console.log(person.getAge());
console.log(person);
复制代码

显示的结果为:

返回为一个json对象,可以直接调用内部的函数、属性。

module.exports 与exports是什么关系?

module.exports = 'personname';

exports.name=function  () {
    console.log('this is person name');
}

调用 的脚本:

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

console.log(person);
console.log(person.name);

执行结果:

personname
undefined

结果:

其实真正的接口是module.exports,exports是一个辅助工具。最终返回到是module.exports,而不是exports。

当module.exports没有任何属性和方法,exports将收集的所有信息都传递给module.exports,如果module.exports已经具有了属性和方法,exports所搜集的信息将会被忽略。

-------------------------------------------------------------------

第二种解说:


exports = module.exports = {};

所以module.exportsexports的区别就是var a={}; var b=a;,a和b的区别

module

首先要明确的一点,module是一个对象 {Object}
当你新建一个文件,比如mo.js,文件内容如下:

1
console.log(module);

然后在CMD里执行这个文件node mo.js,就能看到module其实是一个Module实例,你可以这么理解,NodeJS中定义了一个Module类,这个类中有很多属性和方法,exports是其中的一个属性:

1
2
3
4
5
function Module {
  id : 'blabla',  exports : {},  blabla... } 

当每个js文件在执行或被require的时候,NodeJS其实创建了一个新的实例var module = new Module(),这个实例名叫module
这也就是为什么你并没有定义module这个变量,却能console.log出来而不会报错的原因

module.exports

假设我有一个JS文件内容如下:

console.log(module); //你会看到Module中的exports为空对象{}
module.exports = {
  print : function(){console.log(12345)} } console.log(module); //你会看到Module中的exports对象已经有了print()方法 

有了上面的基础,很容易理解module.export其实是给Module实例中的exports对象中添加方法/属性

exports

通常使用exports的时候,是这么用的:

exports.print = function(){console.log(12345)} 

假设我有一个JS文件内容如下:

console.log(module); //你会看到Module中的exports为空对象{}
console.log(exports); //你会看到Module中的exports为空对象{} module.exports = { print : function(){console.log(12345)} } console.log(module); //你会看到Module中的exports对象有了print()方法 exports.name = '小白妹妹'; console.log(module); //你会看到Module中的exports对象不仅有了print()方法,还有了name属性 

由此也能看出,传说中的exports其实是module.exports的引用,你可以这么理解,NodeJS在你的代码之前悄悄的加了以下代码:

var module = new Module();
var exports = module.exports;

这也就是为什么你并没有定义exports这个变量,却能console.log出来而不会报错的原因

require

当你从外部调用某个模块,require其实是在require什么?^2
require的时候NodeJS会到处去找有没有这个模块,如果有,return的就是module.exports里的东东。

DOs & DONTs

  • √你可以这样:
    module.exports.name = '小白妹妹';
    exports.age = 10;
    module.exports.print = function(){console.log(12345)};
    
    如果只是使用.来添加属性和方法,module.exportsexports混用是完全可以的,这种情况下,感觉exports就是给懒人用的…毕竟能少写几个7个字符呢!
  • √也可以这样:
    module.exports = {
    name = '小白妹妹';
    };
    exports.age = 10;
    module.exports.print = function(){console.log(12345)};
    
  • ×但不可以这样
    module.exports = {
    name = '小白妹妹';
    };
    exports = {age:10}; // exports现在是{age:10}这个对象的引用,不再是module.exports的引用了
    console.log(module); //你会看到Module的exports中只有name属性!!!
    
  • ×也不可以这样
    exports.age = 10; 
    console.log(module); //你会看到Module的exports中多了age属性
    module.exports = {
    name = '小白妹妹';
    };
    console.log(module); //你会看到Module的exports中还是只有name属性!!!
    

    总结

    还是那一句话,module.exportsexports的区别就是var a={}; var b=a;,a和b的区别
    • 改变exports的指向后所添加的exports.xxx都是无效的。因为require返回的只会是module.exports
  • 不能在使用了exports.xxx之后,改变module.exports的指向。因为exports.xxx添加的属性和方法并不存在于module.exports所指向的新对象中。
  • 对于要导出的属性,可以简单直接挂到exports对象上
  • 对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到module.exports对象上,不要和导出属性值混在一起

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值