node.js权威教程读书笔记

133 阅读8分钟

node的REPL环境

var repl=require("repl");
var con=repl.start().context;
con.message="实例消息";
//可以像访问全局变量一样访问testFunction
con.testFunction=function(){
    console.log(con.message)
}
// .clear  可以对全局对象做一个清除 
// 所以在使用了.clear之后不能再使用testFunction方法
//.save  ./aa.js  将在命令行中输入的指令统一保存到aa.js
//.load ./aa.js  可以将保存在aa.js文件的代码都加载到repl环境中

node的基础知识

node中的控制台

console.log方法

  • console.log方法用于进行标准输出流的输出,即在控制台中显示一行字符串

  • 将console.log输出的内容输出到一个具体的日志文件中

    node content_test.js>info.log
    

console.error方法

console.error方法用于进行标准错误输出流的输出,即向控制台中输出一行错误信息

将console.error输出的内容输出到一个具体的日志文件中

node content_test.js>error.log

console.dir方法

console.dir方法用于查看一个对象中的内容并且将该对象的信息输出到控制台中

console.time方法与console.timeEnd方法

在Node.js中,当需要统计一段代码的执行时间时,可以使用console.time方法与console.timeEnd方法,其中console.time方法用于标记开始时间,console.timeEnd方法用于标记结束时间,并且将结束时间与开始时间之间经过的毫秒数在控制台中输出

console.time('small loop');
for(var i=0;i<100000;i++){
    ;
}
console.timeEnd('small loop');
//small loop: 3.928ms

console.assert方法

使用console.trace方法输出当前位置处的栈信息

var user=new Object();
user.name="sasasa";
user.getName=function(){
    return this.name;
}
user.setName=function(name){
    this.name=name
}
console.trace('trace')

console.assert方法

console.assert方法用于对一个表达式的执行结果进行评估,如果该表达式的执行结果为false,则输出一个消息字符串并抛出AssertionError异常。

console.assert(1>2,"sasas")

Node.js中的全局作用域及全局函数

Node.js中的全局作用域

在Node.js中,在一个模块中定义的变量、函数或方法只在该模块中可用,但可以通过exports对象的使用将其传递到模块外部。

console.log(global)

在REPL环境中增加的全局变量和函数都会增加到global上边,但是在js文件中,直接增加则不行。

setTimeout函数与clearTimeout函数

从第三个参数开始,为需要向回调函数中传入的参数。

var tt=setTimeout(function(aa){
    console.log(aa)
},100,1)
clearTimeout(tt)

定时器对象的unref方法与ref方法

setTimeout方法与setInterval函数均返回一个定时器对象,在Node.js中,为定时器对象定义了一个unref方法与一个ref方法

var tt=setTimeout(function(aa){
    console.log(aa)
},100,1)
tt.unref();
tt.ref();

当使用setTimeout函数指定过多少毫秒调用某个回调函数或使用setInterval函数指定每隔多少毫秒调用某个回调函数后,可以使用setTimeout函数或setInterval函数返回的定时器对象的unref方法取消setTimeout函数或setInterval函数中指定的回调函数的调用,仍可使用该定时器对象的ref方法恢复回调函数的调用

与模块相关的全局函数及对象

require

require函数使用一个参数,参数值可以为带有完整路径的模块文件名,也可以为模块名.

node中定义了一个require.main变量,用于检测一个模块是否为应用程序中的主模块。使用方法如下所示(需要将这段代码书写在被检测的模块文件内部)

testModule.js文件

var testVar="wqwq";
exports.testVar=testVar;
if(module==require.main){
    console.log("这是主模块")
}

app.js

var testModule=require('./testModule');
console.log(testModule.testVar);
if(module==require.main){
    console.log("这是主模块11")
}

在node app.js之后会得到

wqwq 这是主模块11

注意:模块在首次加载后将缓存在内存缓存区中。这意味着,对于相同模块的多次引用得到的都是同一个模块对象,这也意味着,对于相同模块的多次引用不会引起模块内代码的多次执行。

testModule.js

var testVar="wqwq";
console.log("正在记载12121")
if(module==require.main){
    console.log("这是主模块")
}
exports.testVar=testVar;

app.js

var testModule=require('./testModule');
var testModule2=require('./testModule');
console.log(testModule.testVar);
if(module==require.main){
    console.log("这是主模块11")
}

“正在记载12121”只会被输出一次

require.resolve

函数查询完整模块名。我们使用require.resolve函数来查询当前目录下testModule.js模块文件的带有完整绝对路径的模块文件名。

注意:使用require.resolve函数查询模块文件名时并不会加载该模块。

console.log(require.resolve('./testModule'))
//C:\nodeWork\testModule.js

require.cache

表达式查看缓存区中的内容.

var testModule=require('./testModule');
console.log(require.cache["C:\\nodeWork\\testModule.js"])
var testModule=require('./testModule');
var testModule2=require('./testModule');
delete require.cache[require.resolve('./testModule')];
var testModule3=require('./testModule');
// 清除缓存之后 会去重新加载./testModule
//正在记载12121
//正在记载12121

__filename变量与__dirname变量

使用__filename变量获取当前文件的完整文件名

var testModule=require('./testModule');
console.log(__filename) //C:\nodeWork\content_test.js

显示testModule.js文件所在目录的完整绝对路径

var testModule=require('./testModule');
console.log(__dirname) //C:\nodeWork

事件处理机制及事件环机制

Emitter触发自己定义的事件

var http=require('http');
var server=http.createServer();
var testFunction=function(){
    console.log(req.url);
    res.end();
}
server.on('request',testFunction)
server.on('custEvent',function(arg1,arg2){
   console.log(arg1,arg2)
})
server.emit('custEvent','111','333')
server.listen(1337,'127.0.0.1')

111 333

newListener\removeListener

监听添加和移除事件的过程

var http=require('http');
var server=http.createServer();
var testFunction=function(req,res){
    console.log(req.url);
    res.end();
}
server.on('removeListener',function(){
    console.log('quxiao')
})
server.on('newListener',function(){
    console.log('add')
})
server.on('request',testFunction);
server.removeListener('request',testFunction);
server.listen(1337,'127.0.0.1')

nmp包管理工具

Node.js框架中的核心模块与文件模块。

❑如何从模块外部访问模块内的变量、对象以及在模块内部定义的方法。

❑如何在使用Node.js框架进行应用程序开发时组织与管理应用程序中需要使用的模块。

❑在Node.js框架中,模块对象具有哪些属性,以及属性值分别代表什么含义。

Node.js框架中所使用的包的基本概念、包的结构,如何自定义一个包,以及如何使用npm包管理工具从网上下载第三方提供的包。

核心模块与文件模块

模块是一个非常重要的概念,它允许我们将第三方类库引入到我们的应用程序中,例如数据库访问类库,它也可以帮助我们将应用程序代码划分为各个不同的模块。通过将应用程序的各种可重用代码编写为各个模块的方法,不仅可以大大减少需要编写的代码量、提高应用程序的开发效率,而且可以使我们的代码变得更加简洁、易读

从模块外部访问模块内的成员

使用exports对象

testModule.js(被调用模块)

var testVar="wqwq";
function aa(){
    console.log(2121)
}
exports.testVar=testVar;
exports.aa=aa;

调用模块

var testModule=require('./testModule');
console.log(testModule.testVar);
testModule.aa()

将模块定义为类

你也可以在模块文件内将exports对象书写为“module.exports”,但是在需要将模块定义为一个类时,只能使用“module.exports”的书写方法。

var _name,_age;
var name="",age=0;
var foo=function (name,age) {
    _name=name;
    console.log(_name)
    _age=age;
}
foo.prototype.GetName=function(){
     return _name
}
foo.prototype.SetName=function(name){
     _name=name
}
foo.prototype.GetAge=function(){
     return _age
}
foo.prototype.SetAge=function(age){
     _age=age
}
foo.prototype.name=name;
foo.prototype.age=age;
module.exports=foo;

组织与管理模块

如果在require函数中只使用如下所示的方法指定文件名,但不指定路径,则Node.js将该文件视为node_modules目录下的一个文件

var foo=require('foo.js')

使用目录来管理模块

接下来,我们在应用程序根目录下创建一个node_modules子目录,在其中创建一个foo子目录,并在其中创建一个index.js文件,其中代码如代码清单4-1所示。在应用程序根目录下创建一个app.js文件,其中代码如代码清单4-2所示,修改第一行代码如下所示。

var foo=require('foo');

就可以将自定义的包放入到module中进行管理啦。

一种更灵活的方式是在应用程序根目录下的node_modules子目录的foo子目录下创建一个package.json文件,并且在其中使用如下所示的代码创建模块名与主文件。

{
    "name":"foo",
    "main":"./lib/foo.js"
}

模块对象的属性

module.id

·module.id:属性值为当前模块的ID。在默认情况下,主模块的ID属性值为“.”,其他模块的ID属性值为该模块文件的绝对路径。在模块文件中可以修改当前模块的ID属性值。

module.filename

属性值为当前模块文件的文件名

module.loaded

属性值为布尔值,当属性值为false时表示模块尚未加载完毕,属性值为true时表示模块加载完毕。

module.parent

属性值为当前模块的父模块对象,即调用当前模块的模块对象。

使用Buffer类处理二进制数据

在客户端JavaScript脚本代码中,对于二进制数据并没有提供一个很好的支持。然而,在处理TCP流或文件流时,必须要处理二进制数据。因此,在Node.js中,定义了一个Buffer类,该类用来创建一个专门存放二进制数据的缓存区

创建Buffer对象

可以使用new关键字来创建该类的实例对象。Buffer类拥有三种形式的构造函数,

  • 第一种是只需将缓存区大小(以字节为单位)指定为构造函数的参数
var buffer=new Buffer(12);
  • 第二种形式的构造函数是直接使用一个数组来初始化缓存区
var buffer=new Buffer([1,2,3,4]);
  • 第三种形式的构造函数直接使用一个字符串来初始化缓存区
var buffer=new Buffer("sasas");

字符串的长度与缓存区的长度

在Node.js中,一个字符串的长度与根据该字符串所创建的缓存区的长度并不相同。因为在计算字符串的长度时,以文字作为一个单位,而在计算缓存区的长度时,以字节作为一个单位。

var str="我喜爱编程"
var buffer=new Buffer(str);
console.log(str.length)  //5
console.log(buffer.length) //15