模块系统

在 Node.js 中,创建一个模块非常简单,如下我们创建一个 main.js 文件,代码如下:

var hello = require('./hello');
hello.world();

以上实例中,代码 require(’./hello’) 引入了当前目录下的 hello.js 文件(./ 为当前目录,node.js 默认后缀为 js)。
关于require的作用请看我的另一篇require的介绍,总之,就是require引入的时候会执行模块的所有代码,模块里定义的变量作用域值在模块内。所以需要使用模块里的相应变量或者方法的时候,要加上exports,如下面例子:

//hello.js
function Hello()
{
    var name;
    this.setName=function(thyName){
        name=thyName;
    };
    this.sayHello=function(){
        console.log('Hello'+name);
    };
}
module.exports=Hello;
var Hello=require('./hello');
hello=new Hello();
hello.setName('czm');
hello.sayHello();

require的优先级:

函数

可以直接定义一个函数再调用:

function say(word) {
  console.log(word);
}

function execute(someFunction, value) {
  someFunction(value);
}

execute(say, "Hello");

也可以不定义直接在函数里定义函数,也称匿名函数:

function execute(someFunction, value) {
  someFunction(value);
}

execute(function(word){ console.log(word) }, "Hello");

路由

server.js

var http=require('http');
var url=require('url');
function start(route){
    function onRequest(request,response){
        var pathname=url.parse(request.url).pathname;
        console.log("Request for"+pathname+"received.");
        route(pathname);
        response.writeHead(200,{"Content-Type":"text/plain"});
        response.write("Hello World");
        response.end();
    }
    http.createServer(onRequest).listen(8888);
    console.log("Server has started.");
}
exports.start=start;

router.js

function route(pathName){
    console.log("About to route a request for"+pathName);
}
exports.route=route;

index.js

var server=require("./server");
var router=require("./router");
server.start(router.route);

运行index.js,就可以用浏览器浏览 http://127.0.0.1:8888/

全局对象

注意: 永远使用 var 定义变量以避免引入全局变量,因为全局变量会污染 命名空间,提高代码的耦合风险。
Node.js提供下面一些全局对象:

  1. __filename 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。
  2. __dirname 表示当前执行脚本所在的目录。
  3. setTimeout(cb, ms) 全局函数在指定的毫秒(ms)数后执行指定函数(cb)。:setTimeout() 只执行一次指定函数。返回一个代表定时器的句柄值。
  4. clearTimeout( t ) 全局函数用于停止一个之前通过 setTimeout() 创建的定时器。 参数 t 是通过 setTimeout() 函数创建的定时器。
// 两秒后执行以上函数
var t = setTimeout(printHello, 2000);

// 清除定时器
clearTimeout(t);

常用工具

util.inherits
util.inherits(constructor, superConstructor)是一个实现对象间原型继承 的函数。

var util=require('util');
function Base(){
    this.name='base';
    this.base=1991;
    this.sayHello=function(){
        console.log('Hello'+this.name);
    };
}
Base.prototype.showName=function(){
    console.log(this.name);
};
function Sub(){
    this.name='sub';
}
util.inherits(Sub,Base);
var objBase=new Base();
objBase.showName();
objBase.sayHello();
console.log(objBase);
var objSub=new Sub();
objSub.showName();
//objSub.sayHello();
console.log(objSub);

输出结果:

Sub 仅仅继承了Base 在原型中定义的函数,而构造函数内部创造的 base 属 性和 sayHello 函数都没有被 Sub 继承。
同时,在原型中定义的属性不会被console.log 作 为对象的属性输出。

util.inspect
util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出。它至少接受一个参数 object,即要转换的对象。
showHidden 是一个可选参数,如果值为 true,将会输出更多隐藏信息。
depth 表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多 少。如果不指定depth,默认会递归2层,指定为 null 表示将不限递归层数完整遍历对象。 如果color 值为 true,输出格式将会以ANSI 颜色编码,通常用于在终端显示更漂亮 的效果。

util.isArray(object)
如果给定的参数 “object” 是一个数组返回true,否则返回false。

util.isRegExp(object)
如果给定的参数 “object” 是一个正则表达式返回true,否则返回false。

util.isDate(object)
如果给定的参数 “object” 是一个日期返回true,否则返回false。

util.isError(object)
如果给定的参数 “object” 是一个错误对象返回true,否则返回false。