module.exports和exports
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了module.exports和exports相关的知识,希望对你有一定的参考价值。
首先要认识module.exports和exports分别是什么。
在nodejs中,提供了exports 和 require 两个对象,其中 exports 是模块公开的接口,require 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。但exports是引用 module.exports的值。module.exports 被改变的时候,exports不会被改变,而模块导出的时候,真正导出的执行是module.exports,而不是exports。
每一个node.js执行文件,都自动创建一个module对象,同时,module对象会创建一个叫exports的属性,初始化的值是 {}
module.exports = {};
关于这两个的知识点,目前了解的主要在两个方面:
第一个就是在exports抛出的接口中,如果你希望你的模块就想为一个特别的对象类型,请使用module.exports;如果希望模块成为一个传统的模块实例,请使用exports.xx方法;module.exports才是真正的接口,exports只不过是它的一个辅助工具。最终返回给调用的是module.exports而不是exports。也就是构造函数必须使用module.exports。如下面案例:
新建一个time.js:
module.exports=function(year,month,day){ this.year=year; this.month=month; this.day=money; this.say=function(){ console.log(\'今天是:\'+this.year+\',年\'+this.month+\'月,月薪为:\'+this.day+\'日;\') } };
这里的module.exports被赋予了一个构造函数;再新建一个main.js,其中引入time.js这个模块,把exports方法接受进来,main.js代码如下:
var Hello=require(\'./time\'); var hello=new Hello(\'2017\',\'9\',\'27\') hello.say();
进入node环境,运行main.js,可以看到,已经打印出来:
而在time.js中,我们是赋予了exports一个函数 ,当然,也可以采用匿名函数的方式;见代码:
function hello(year,month,day){ this.year=year; this.month=month; this.day=day; this.say=function(){ console.log(\'今天是:\'+this.year+\'年\'+this.month+\'月,\'+this.day+\'日;\') } } module.exports=hello;
以上modle.exports,这个模块很明显是一个特别的对象模型;那如果采用对象实例的方法该如何实现呢?其实也很简单,只需要给exports对象负值一个新的方法即可;见下面代码:
function hello(year,month,day){ this.year=year; this.month=month; this.day=day; this.say=function(){ console.log(\'今天是:\'+this.year+\'年\'+this.month+\'月,\'+this.day+\'日;\') } } var Hello = new hello(\'2017\',\'9\',\'27\') exports.add = Hello;
这时候用的就是exports了
在time.js中,依然是一个构造函数,声明了一个变量Hello,然后再把Hello赋值给exports自定义的add方法;那么在main.js中,由于add已经是exports的一个自定义的实例方法了,因此我们可以直接这么调用它:Hello.add.say();见代码:
var Hello=require(\'./time\'); Hello.add.say()
输出一样,结束。
第二个:
首先来看下这个问题:
test.js
var a = {name: 1};
var b = a;
console.log(a);
console.log(b);
b.name = 2;
console.log(a);
console.log(b);
var b = {name: 3};
console.log(a);
console.log(b);
运行 test.js 结果为:
{ name: 1 }
{ name: 1 }
{ name: 2 }
{ name: 2 }
{ name: 2 }
{ name: 3 }
解释:a 是一个对象,b 是对 a 的引用,即 a 和 b 指向同一块内存,所以前两个输出一样。当对 b 作修改时,即 a 和 b 指向同一块内存地址的内容发生了改变,所以 a 也会体现出来,所以第三四个输出一样。当 b 被覆盖时,b 指向了一块新的内存,a 还是指向原来的内存,所以最后两个输出不一样。是不是和Java也有点像。
明白了上述例子后,我们只需知道三点就知道 exports 和 module.exports 的区别了:
- module.exports 初始值为一个空对象 {}
- exports 是指向的 module.exports 的引用
- require() 返回的是 module.exports 而不是 exports
我们可以这样:
exports = module.exports = {...}
经常看到这样的写法:
exports = module.exports = {...}
上面的代码等价于:
module.exports = {...}
exports = module.exports
原理很简单:module.exports 指向新的对象时,exports 断开了与 module.exports 的引用,那么通过 exports = module.exports 让 exports 重新指向 module.exports。
继续看一个例子:
foo.js
exports.a = function(){
console.log(\'a\')
}
exports.a = 1
test.js
var x = require(\'./foo\');
console.log(x.a)
看到这里,相信大家都看到答案了,exports是引用 module.exports的值。module.exports 被改变的时候,exports不会被改变,而模块导出的时候,真正导出的执行是module.exports,而不是exports
再看看下面例子
foo.js
exports.a = function(){
console.log(\'a\')
}
module.exports = {a: 2}
exports.a = 1
test.js
var x = require(\'./foo\');
console.log(x.a)
result:
2
exports在module.exports 被改变后,失效。
javascript里面有一句话,函数即对象,View 是对象,module.export =View, 即相当于导出整个view对象。外面模块调用它的时候,能够调用View的所有方法。不过需要注意,只有是View的静态方法的时候,才能够被调用,prototype创建的方法,则属于View的私有方法。
foo.js
function View(){
}
View.prototype.test = function(){
console.log(\'test\')
}
View.test1 = function(){
console.log(\'test1\')
}
module.exports = View
test.js
var x = require(\'./foo\');
console.log(x) //{ [Function: View] test1: [Function] }
console.log(x.test) //undefined
console.log(x.test1) //[Function]
x.test1() //test1
##var app = exports = module.exports = {};
其实,当我们了解到原理后,不难明白这样的写法有点冗余,其实是为了保证,模块的初始化环境是干净的。同时也方便我们,即使改变了 module.exports 指向的对象后,依然能沿用 exports的特性
exports = module.exports = createApplication;
/**
* Expose mime.
*/
exports.mime = connect.mime;
例子,当中module.exports = createApplication
改变了module.exports了,让exports失效,通过exports = module.exports的方法,让其恢复原来的特点。
##exports.init= function(){}
这种最简单,直接就是导出模块 init的方法。
##var mongoose = module.exports = exports = new Mongoose;
集多功能一身的写法
以上是关于module.exports和exports的主要内容,如果未能解决你的问题,请参考以下文章