node.js学习日记(4)

模块

一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。

创建模块

1、创建hello.js

exports.world = function() {
  console.log('Hello World');
}

exports 是模块公开的接口,在此例中,world是对外看到的方法名,也就是接口。
2、引入模块

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

在之前的笔记中提到过,和引入node.js本身的模块不同,引入自己书写的模块时,不能只写文件名称,需表明路径,此例表示引入当前目录下的hello.js文件。默认后缀为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('BYVoid'); 
hello.sayHello(); 

模块接口从exports.world = function(){} 变成了 module.exports = Hello
在外部引用该模块时,其接口对象就是要输出的 Hello 对象本身,而不是原先的 exports。

服务端的模块放在哪里

require方法接受以下几种参数的传递:

  • http、fs、path等,原生模块。
  • ./mod或../mod,相对路径的文件模块。
  • /pathtomodule/mod,绝对路径的文件模块。
  • mod,非原生模块的文件模块。

优先级关系:

  • 文件模块的缓存
  • 原生模块的缓存区
  • 原生模块
    • 以http模块为例,尽管在目录下存在一个http/http.js/http.node/http.json文件,require(“http”)都不会从这些文件中加载,而是从原生模块中加载。
  • 文件模块

函数

在JavaScript中,一个函数可以作为另一个函数接收一个参数。我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数。Node.js中函数的使用与Javascript类似。

  • 以HTTP服务器为例
var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8888);
var http = require("http");

function onRequest(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}

http.createServer(onRequest).listen(8888);

第一段代码向 createServer 函数传递了一个匿名函数。第二段代码则是先定义一个函数,然后传递。

路由

提供请求的URL和其他需要的GET及POST参数,随后路由需要根据这些数据来执行相应的代码。
需要的所有数据都会包含在request对象中,该对象作为onRequest()回调函数的第一个参数传递。但是为了解析这些数据,我们需要额外的Node.JS模块,分别是url和querystring模块。

                             url.parse(string).query
                                           |
           url.parse(string).pathname      |
                       |                   |
                       |                   |
                     ------ -------------------
http://localhost:8888/start?foo=bar&hello=world
                                ---       -----
                                 |          |
                                 |          |
              querystring(string)["foo"]    |
                                            |
                         querystring(string)["hello"]

把路由和服务器整合起来

  • router.js
function route(pathname) {
  console.log("About to route a request for " + pathname);
}

exports.route = route;

输出route作为接口。

  • 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;

输出start作为接口。上段代码中的route方法作为start方法的参数,并在其中调用。url.parse(request.url).pathname用来获取路径名称。

  • index.js
var server = require("./server");
var router = require("./router");

server.start(router.route);

引入自己编写的server和router模块。调用start方法,并将route方法作为参数传递。
在命令行输入 node index.js 启动应用。随后请求一个URL,浏览器访问http://localhost(或127.0.0.1):8888(你监听的端口号)/(任意路径名)
这里写图片描述

这里写图片描述

全局对象


Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性。
当你定义一个全局变量时,这个变量同时也会成为全局对象的属性。
注意: 永远使用var定义变量以免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。

全局对象举例

  • __filename
    • 当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。
  • __dirname
    • 当前执行脚本所在的目录。
  • console
    • 提供控制台标准输出
    • console.log() 接受若干 个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则 以类似于C 语言 printf() 命令的格式输出。
    • console.time(label) 表示计时开始,console.timeEnd(label) 表示计时结束。
    • console.trace() 向标准错误流输出当前的调用栈。
  • process
    • 是一个全局变量,即 global 对象的属性。
    • 描述当前Node.js 进程状态的对象,提供了一个与操作系统的简单接口。
// 输出到终端
process.stdout.write("Hello World!" + "\n");
// 通过参数读取
process.argv.forEach(function(val, index, array) {
   console.log(index + ': ' + val);
});
// 获取执行路局
console.log(process.execPath);
// 平台信息
console.log(process.platform);

这里写图片描述
首先通过标准输出流进行了打印。argv 属性返回一个数组,由命令行执行脚本时的各个参数组成。它的第一个成员总是node,第二个成员是脚本文件名,其余成员是脚本文件的参数。后面两个参数则是Node的路径和平台系统。
process还有很多有用的方法和属性。

// 输出当前目录
console.log('当前目录: ' + process.cwd());
// 输出当前版本
console.log('当前版本: ' + process.version);
// 输出内存使用情况
console.log(process.memoryUsage());

这里写图片描述

常用工具

  • 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有三个在构造函数内定义的属性和一个原型中定义的函数。Sub 仅仅继承了Base 在原型中定义的函数。
输出为:

base 
Hello base 
{ name: 'base', base: 1991, sayHello: [Function] } 
sub 
{ name: 'sub' }
  • util.inspect
    util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换为字符串的方法,通常用于调试和错误输出。

自己加油加油 笨鸟后飞也要飞呀飞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值