module.exports 与 exports
注意:
1 对于要导出的属性,可以简单直接挂到 exports 对象上
2 对于类,为了直接使导出的内容作为类的构造器可以让调用者使用 new 操作符创建实例对象,应该把构造函数挂到 module.exports 对象上,不要和导出属性值混在一起
var a = new Object(); // a相当于module.exports
var b = a; // b相当于exports
例子 exports
导出模块
// rocker.js
exports.name = function() {
console.log('My name is fang');
};
导入模块
var rocker = require('./rocker.js');
rocker.name(); // 'My name is fang'
例子 module.exports
每一个 node.js 执行文件,都自动创建一个 module 对象。
同时, module 对象会创建一个叫 exports 的属性,初始化的值是 {} 。即 module.exports = {}
。
导出模块
module.exports = function(name, age) {
this.name = name;
this.age = age;
this.about = function() {
console.log(this.name +' is '+ this.age +' years old');
};
};
导入模块
var Rocker = require('./rocker.js');
var r = new Rocker('fang', 23);
r.about(); // fang is 23 years old
例子 module.exports
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
扩展阅读
Nodejs的模块系统以及require的机制
原 https://www.cnblogs.com/bq-med/p/9008190.html
Nodejs 有一个简单的模块加载系统。在 Nodejs 中,文件和模块是一一对应的(每个文件被视为一个独立的模块)。
require方能看到的只有module.exports这个对象,它是看不到exports对象的,而我们在编写模块时用到的exports对象实际上只是对module.exports的引用。
每一个node.js执行文件,都自动创建一个module对象,同时,module对象会创建一个叫exports的属性,初始化的值是 {}
module.exports = {};
首先说一个概念:
ECMAScript的变量值类型共有两种:
- 基本类型 (primitive values) : 包括Undefined, Null, Boolean, Number和String五种基本数据类型;
- 引用类型 (reference values) : 保存在内存中的对象们,不能直接操作,只能通过保存在变量中的地址引用对其进行操作。
我们今天要讨论的exports和module.exports属于Object类型,属于引用类型。
看下面的例子:
var module = { exports:{ name:"我是module的exports属性" } }; var exports = module.exports; //exports是对module.exports的引用,也就是exports现在指向的内存地址和module.exports指向的内存地址是一样的 console.log(module.exports); // { name: '我是module的exports属性' } console.log(exports); // { name: '我是module的exports属性' } exports.name = "我想改一下名字"; console.log(module.exports); // { name: '我想改一下名字' } console.log(exports); // { name: '我想改一下名字' } //看到没,引用的结果就是a和b都操作同一内存地址下的数据
回到nodejs中,module.exports初始的时候置为{},exports也指向这个空对象。
exports.name = function(x){ console.log(x); }; //和下面这个一毛一样,因为都是修改的同一内存地址里的东西 module.exports.name = function(x){ console.log(x); };
但是这样写就有了区别了:
exports = function(x){ console.log(x); }; //上面的 function是一块新的内存地址,导致exports与module.exports不存在任何关系,而require方能看到的只有module.exports这个对象,看不到exports对象,所以这样写是导不出去的。 //下面的写法是可以导出去的。说句题外话,module.exports除了导出对象,函数,还可以导出所有的类型,比如字符串、数值等。 module.exports = function(x){ console.log(x); };
Nodejs 中的每一个模块都会自动创建一个 module 对象,同时 module 对象下有一个叫 exports 的属性,可以将某个类的实例赋值给 module.exports,从而导出这个类的实例。在模块被执行前,Nodejs 会将 module.exports 的值赋于全局变量 exports ,以便 module.exports.f = ... 可以更简洁的写成 exports.f = ... 。注意:就像所有变量一样,如果重新给 exports 赋值,它就不再绑定到 module.exports 了,也不会导出指定模块。
foo1.js
/** *导入方式:var foo = require("./foo1.js"); */ function Foo() {} Foo.prototype.hello = function() { console.log("hello Nodejs!"); } module.exports = new Foo();
foo2.js
/** *导入方式:var Foo = require("./foo2.js"); var foo = new Foo(); */ function Foo() {} Foo.prototype.hello = function() { console.log("hello Nodejs!"); } module.exports = Foo;
foo3.js
/** *导入方式:var foo = require("./foo3.js"); */ exports.hello = function() { console.log("hello Nodejs!"); }