module.exports
使用方式:
代码语言:javascript复制// File Name: hello.js
function greet() {/*......*/}
// 有下面这两种写法:
// 1.
module.exports = greet;
// 2.
module.exports = {
greet:greet
}
它们的调用方式是不一样的
第一种是这样调用:
代码语言:javascript复制var greet = require('./hello');
greet(s);
第二种是这样调用:
代码语言:javascript复制var hello = require('./hello');
hello.greet(s);
总结:第二种更好。
注意事项:
代码语言:javascript复制var module = {
id: 'hello',
exports: {}
};
//load()函数最终返回module.exports:
var load = function (exports, module) {
// hello.js的文件内容
...
// load函数返回:
return module.exports;
};
var exported = load(module.exports, module);
这个可以改变原始exports对象:
代码语言:javascript复制exports.foo = function () { return 'foo'; };
而
代码语言:javascript复制exports = function () { return 'foo'; };
只是改变了形参exports的引用(/指向),而实际的module.exports还是指向空对象{}
process.nextTick和setImmediate的区别
-
process.nextTick
方法可以在当前"执行栈"的尾部----下一次Event Loop(主线程读取"任务队列")之前----触发回调函数。 -
setImmediate
方法则是在当前"任务队列"的头部添加事件,也就是说,它指定的任务总是在下一次Event Loop时执行,这与setTimeout(fn, 0)
很像。
fs.readFile和fs.writeFile
代码语言:javascript复制'use strict';
var fs = require('fs');
// ======test1======
// fs.readFile('sample.txt', 'utf-8', function (err, data) {
// if (err) {
// console.log(err, data);
// } else {
// console.log(err, data);
// }
// });
// ======test1 end======
// ======test2======
fs.readFile('sample.png', function (err, data) {
if (err) {
console.log(err);
} else {
// ======test2.1======
// console.log(data);
// console.log(data.length ' bytes');
// var text = data.toString('utf-8');
// console.log(text);
// console.log(text.length ' bytes');
// ======test2.1 end======
// ======test2.2======
fs.writeFile('output.png', data, function (err) {
if (err) {
console.log(err);
} else {
console.log('ok.');
}
});
// ======test2.2 end======
}
});
// ======test2 end======
createReadStream和createWriteStream
代码语言:javascript复制'use strict';
var fs = require('fs');
// ===test1===
// 打开一个流:
// var rs = fs.createReadStream('sample.txt', 'utf-8');
// rs.on('data', function (chunk) {
// console.log('DATA:')
// console.log(chunk);
// });
// rs.on('end', function () {
// console.log('END');
// });
// rs.on('error', function (err) {
// console.log('ERROR: ' err);
// });
// ===test1 end===
// ===test2===
var ws1 = fs.createWriteStream('output1.txt', 'utf-8');
ws1.write('使用Stream写入文本数据...n');
ws1.write('END.');
ws1.end();
var ws2 = fs.createWriteStream('output2.txt');
ws2.write(new Buffer('使用Stream写入二进制数据...n', 'utf-8'));
ws2.write(new Buffer('END.', 'utf-8'));
ws2.end();
// ===test2 end===
pipe()
代码语言:javascript复制'use strict';
var fs = require('fs');
var rs = fs.createReadStream('sample.txt');
var ws = fs.createWriteStream('copied.txt');
rs.pipe(ws);
Node中的全局对象
Node提供以下几个全局对象,它们是所有模块都可以调用的。
- global:表示Node所在的全局环境,类似于浏览器的window对象。需要注意的是,如果在浏览器中声明一个全局变量,实际上是声明了一个全局对象的属性,比如var x = 1等同于设置window.x = 1,但是Node不是这样,至少在模块中不是这样(REPL环境的行为与浏览器一致)。在模块文件中,声明var x = 1,该变量不是global对象的属性,global.x等于undefined。这是因为模块的全局变量都是该模块私有的,其他模块无法取到。
- process:该对象表示Node所处的当前进程,允许开发者与该进程互动。
- console:指向Node内置的console模块,提供命令行环境中的标准输入、标准输出功能。
Node还提供一些全局函数。
- setTimeout():用于在指定毫秒之后,运行回调函数。实际的调用间隔,还取决于系统因素。间隔的毫秒数在1毫秒到2,147,483,647毫秒(约24.8天)之间。如果超过这个范围,会被自动改为1毫秒。该方法返回一个整数,代表这个新建定时器的编号。
- clearTimeout():用于终止一个setTimeout方法新建的定时器。
- setInterval():用于每隔一定毫秒调用回调函数。由于系统因素,可能无法保证每次调用之间正好间隔指定的毫秒数,但只会多于这个间隔,而不会少于它。指定的毫秒数必须是1到2,147,483,647(大约24.8天)之间的整数,如果超过这个范围,会被自动改为1毫秒。该方法返回一个整数,代表这个新建定时器的编号。
- clearInterval():终止一个用setInterval方法新建的定时器。
- require():用于加载模块。
- Buffer():用于操作二进制数据。
Node提供两个全局变量,都以两个下划线开头。
- __filename:指向当前运行的脚本文件名。
- __dirname:指向当前运行的脚本所在的目录。
除此之外,还有一些对象实际上是模块内部的局部变量,指向的对象根据模块不同而不同,但是所有模块都适用,可以看作是伪全局变量,主要为module, module.exports, exports等。
on和addListener
https://github.com/nodejs/node/blob/v1.x/lib/events.js#L244
源码第244行:
EventEmitter.prototype.on = EventEmitter.prototype.addListener;