(译)Node.js的模块-exports和module.exports
原文标题:Node.js Module – exports vs module.exports
原文链接:http://www.hacksparrow.com/node-js-exports-vs-module-exports.html
exports 和 module.exports 有什么区别?
你一定很熟悉 Node.js 模块中的用来在你的模块中创建函数的 exports 对象,就像下面这样。
创建一个叫做rocker.js的文件:
exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
然后可以在另外一个文件中调用 rocker.js :
var rocker = require('./rocker.js');
rocker.name(); // 'My name is Lemmy Kilmister'
但是,module.exports 到底什么?它是合法的吗?
令人吃惊的是:module.exports 是真实存在的。exports 只不过是 module.exports 的帮手而已。你的模块直接返回返回 module.exports 给调用者,而不是 exports 。所有的 exports 做的工作实际上是收集属性,如果 module.exports 当前没有任何属性,exports便将收集到的属性添加到 module.exports 上。如果 module.exports
已经存在若干属性,所以 exports 上的属性都会被忽略。
修改 rocker.js 文件:
module.exports = 'ROCK IT!';
exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
在另一个文件中调用 rocker.js:
var rocker = require('./rocker.js');
rocker.name(); // TypeError: Object ROCK IT! has no method 'name'
上述例子中的 rocker 模块完全将 exports.name 忽略了,只返回了一个 String 字符串:'ROCK IT!' 。 从这个例子你大概明白了:你的模块并不一定总是一个模块的实例(module instance),它可以是任何合法的 JavaScript 对象——boolean, number, date, JSON, string, function, array 和其他的。你的模块可以是任何你设置的 module.exports 的值。如果你没有明确地为 module.exports 设置任何值,那么 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('Ozzy', 62);
r.about(); // Ozzy is 62 years old
在这时候你的模块是一个数组:
module.exports = [
'Lemmy Kilmister',
'Ozzy Osbourne',
'Ronnie James Dio',
'Steven Tyler',
'Mick Jagger'
];
而你可以这样使用:
var rocker = require('./rocker.js');
console.log('Rockin in heaven: ' + rocker[2]); //Rockin in heaven: Ronnie James Dio
现在你应该明白了点什么——如果你想让你的模块返回一个特殊的对象类型,比如构造函数,那么你得使用 module.exports ;如果你只想模块作为一个典型的模块实例(module instance),那么就用exports。
把属性添加到 module.exports 中和添加到 exports 中的结果是一样的。比如像这样:
module.exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
其实和下面的是一样的:
exports.name = function() {
console.log('My name is Lemmy Kilmister');
};
但是要注意,他们不是同一个东西。就像之前说的一样,exports 只不过是 module.exports 的帮手而已。话虽如此,exports 还是推荐的对象,除非你想把你模块的对象类型从传统的模块实例(module instance)修改为其他的。
只要你没有使用赋值运算重写 module.exports 对象,任何添加到 module.exports 和 exports 的属性都能够在 require 模块中。
比如这是你的模块中的内容:
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
下面的代码可以很好的工作:
var rocker = require('./rocker.js');
console.log('%s is %s', rocker.name, rocker.age); // Lemmy Kilmister is 68
但是,如果你在你的模块中重写了 module.exports 中的任何地方,代码便会出错:
module.exports = 'LOL';
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
或者这样:
module.exports.age = 68;
exports.name = 'Lemmy Kilmister';
module.exports = 'WTF';
顺序没有关系,rocker.age 和 rocker.name 将显示为 undefined。
并且注意:只是因为 module.exports 和 exports 都能输出模块,并不意味这你可以组合使用。我的建议是,坚持使用 exports.*,明白module.exports
我希望这篇文章能帮助你理解exports和module.exports之间的不同,并且能进一步的理解模块在Node.js中是怎么工作的。
(完)
翻译水平有待提高,所翻译的博文并不是按照原文一句一句翻译,而是添加了自己对文章的理解。如有不正之处,欢迎指正!
个人笔记,仅供参考。
参考:
http://www.hacksparrow.com/node-js-exports-vs-module-exports.html
(译)Node.js的模块-exports和module.exports的更多相关文章
- Node.js学习之(第二章:exports和module.exports)
前言 Node中,每个模块都有一个exports接口对象,我们需要把公共的方法或者字符串挂载在这个接口对象中,其他的模块才可以使用. Node.js中只有模块作用域,默认两个模块之间的变量,方法互不冲 ...
- node.js模块中exports和module.exports的区别
Node应用由模块组成,采用CommonJS模块规范. 根据这个规范,每个文件就是一个模块,有自己的作用域.在一个文件里面定义的变量.函数.类,都是私有的,对其他文件不可见. CommonJS规范规定 ...
- Node.js模块导出exports 和 module.exports 的区别
原文: https://blog.csdn.net/Pwiling/article/details/51958693 每一个node.js执行文件,都自动创建一个module对象,同时,module对 ...
- Node.js中exports与module.exports的区别
原文:http://www.hacksparrow.com/node-js-exports-vs-module-exports.html 你肯定对Node.js模块中用来创建函数的exports对象很 ...
- node (02 CommonJs 和 Nodejs 中自定义模块)顺便讲讲module.exports和exports的区别 dependencies 与 devDependencies 之间的区别
CommonJS 规范的提出,主要是为了弥补当前 JavaScript 没有标准的缺陷.它的终极目标就是:提供一个类似 Python,Ruby 和 Java 语言的标准库,而不只是停留在小脚本程序的阶 ...
- Node.js之exports与module.exports
每一个node.js执行文件,都自动创建一个module对象,同时,module对象会创建一个叫exports的属性,初始化的值是 {} module.exports = {}; Node.js为了方 ...
- node.js中的exports和module.exports
不同的编程语言都有各自的代码组织和复用的方式,如.net.php中的命名空间,python中的import,ruby中的module等,来避免命名空间污染.一直都没搞清楚node中的exports和m ...
- Node.js exports与module.exports的关系
今天搜索module.exports时看到CNode社区上发的Hack Sparrow一篇相关文章的链接 Node.js Module – exports vs module.exports 一篇5年 ...
- 理解node模块的exports和module.exports
exports是module.exports的引用,即var exports = module.exports.在一个模块的开头,这两个值都指向同一个空对象:exports = module.expo ...
随机推荐
- springmvc入门demo
目录结构: package com.wyl; import org.springframework.stereotype.Controller; import org.springframework. ...
- 《Pointers On C》读书笔记(第五章 操作符和表达式)
1.C语言操作符优先级表 2.算术操作符中%(取模操作符)只适用于整型类型,其余几个操作符(+.-.*./)既适用于整型类型也适用于浮点类型.当/操作符的两个操作数都是整型时,它执行整除运算,其它情况 ...
- Drupal7模块multiselect使用
Drupal二次开发的时候,我们时常要使用到多选列表,但是官方默认的多选下拉列表,是在不敢恭维如下图所示: 不过难看不可怕,Drupal有两万第三方模块做支撑,只有你想不到,没有找不到的. 功夫不负有 ...
- 合作开发,导入MyEclipse项目报错问题
因工作原因,同事将他的java项目交接给了我.和平时的交接一样.他把他最新的源代码,打成压缩包,发给我.我解压后,使用myeclipse开发工具,通过导入,将项目导入到我的开发工具中,这个时候有一个问 ...
- 设计模式入门之桥接模式Bridge
Abstraction:抽象部分的父类,定义须要实现的接口.维护对实现部分的引用,从而把实现桥接到Implementor中去 Implementor:实现部分的接口 RefinedAbstractio ...
- 嵌入式系统 Boot Loader
基于嵌入式系统中的 OS 启动加载程序 ―― Boot Loader 的概念.软件设计的主要任务以及结构框架等内容.
- 用 rsync 同步本地和服务器的文件
参考 DigitalOcean 安装 For Debian/Ubuntu: sudo apt-get install rsync For OpenSUSE/Fedora: sudo yum insta ...
- 注册表:无法打开 XXX 由于某个错误无法打开该密钥。详细信息:拒绝访问
错误原因:没有注册表用户权限. 正确添加用户权限的步骤如下:(跟着图片步骤) 右击该项,权限: 选中想要添加为当前所有者的用户后,点击应用.如果没用户显示,可以从“其他用户或组”中添加进来. 权限添加 ...
- HDU1171:Big Event in HDU(多重背包分析)
通过分析,要使A>=B并且差值最小.所以只要使sum/2的容量下,B最大就Ok了 #include<iostream> #include<cstdio> #include ...
- zoj 2376 Ants
#include<stdio.h> #include<stdlib.h> ]; int main(void) { int t,n,m,i,len,max,min,mx,mi; ...