闭包:有权访问另一个函数作用域内变量的函数。
(function(){...}())
(function(){...})()
函数名只是一个标识,是指向函数的指针,而函数名带上()才是执行函数。
匿名自执行函数:没有方法名的函数。
注:匿名自执行函数不加返回值,外部不能访问。
通过“匿名函数.函数名()”的方式进行调用。
var calculator=(function(){
function add(){
return 10;
}
return {
add:add
}
})();
console.log(calculator.add());
代码的扩展与维护
var calculator=(function(cal){
function add(){
return 10;
}
cal.add=add;
return cal;
})(calculator || {});
//扩展
var calculator=(function(cal){ //cal:想象成形参。
cal.substract=function(){
return 'xx';
}
return cal;
})(calculator||{}); //calculator:想象成实参。
//“calculator||{}”:当扩展该模块时,判断calculator函数是否存在,如果存在就使用已存在的,如果不存在就重新创建。
//好处:不需要考虑顺序,后写的同名函数不会覆盖之前的同名函数,而是在其基础上进行扩展。
console.log(calculator.add());
console.log(calculator.substract());
JavaScript包括ECMAScript,DOM,BOM三部分
CMD:command(命令提示符)
使用“node 文件名.js”执行文件
REPL运行环境:(Read-Eval-Print-Loop)当开发者输入JavaScript表达式,按下[Enter]键后,REPL运行环境中将显示该表达式的运行结果。然后等待下一次用户输入,这种输入和显示结果的形式是循环的。
打开终端,输入node命令并按下【Enter】键,即可进入REPL运行环境。
按“Ctrl+D”或“Ctrl+C+C”终止Node REPL
global对象
在Node.js中,默认就是模块化的,默认声明的变量、函数,都属于当前文件模块,都是私有的。
global对象类似于浏览器中的Window对象,用于定义全局命名空间,所有全局变量(除global本身之外)都是global对象的属性。通过“global.属性”的方式获取和赋值。
require()、exports、module.exports
exports:模块公开的接口
require():用于从外部获取一个模块的接口,即获取模块的exports对象。
要在一个文件模块中获取其他文件模块的内容,要使用require()函数加载这个模块,在被加载的模块中使用exports或module.exports对象向外开放变量、函数等。require()函数的作用是加载文件并获取该文件中的module.exports对象接口。
exports 和 module.exports区别:
exports指向module.exports的引用,module.exports初始值为一个空对象{}。module.exports可以单独定义,返回数据类型,而exports只能返回一个object对象。
JavaScript的执行环境是单线程的。单线程一次只能完成一个任务,如果有多个任务,就需要等待前面一个任务完成后,再执行后面的一个任务。
包:在模块的基础上更进一步的组织JavaScript代码的目录。
NPM:Node.js Package Manage,Node.js---------------包管理工具。
NPM常用命令:
命令 | 作用 |
---|---|
npm init [-y] | 初始化一个package.json文件 |
npm install 包名 | 安装一个包 |
npm install -save 包名 | 将安装的包添加到package.json的依赖中 |
npm install -g 包名 | 安装一个命令行工具 |
npm docs 包名 | 查看包的文档 |
npm root -g | 查看全局包安装路径 |
npm config set prefix ”路径“ | 修改全局包安装路径 |
npm list | 查看当前目录下安装的所有包 |
npm list -g | 查看全局包的安装路径下所有的包 |
npm uninstall 包名 | 卸载当前目录下某个包 |
npm uninstll -g 包名 | 卸载全局安装路径下的某个包 |
npm update 包名 | 更新当前目录下某个包 |
Node.js文件操作API由fs(File System)模块提供,异步的fs.readFile()和同步的fs.readFileSync()。
比起同步,异步函数性能更高,速度更快,而且没有阻塞。
载入模块:
var fs = require('fs');
异步:
文件写入
fs.writeFile(file,data[,options],callback);
//callback:回调函数,只包含错误信息参数(err),在写入失败时返回
如果文件已存在,就会覆盖同名文件的内容。
文件追加
appendFile(file,data[,options],callback);
文件读取
fs.readFile(file[,options],callback);
//callback:err错误信息参数;data:读取到的信息
//用data.toString()方法把读取的二进制数据转换为人们识别的字符。
文件复制
先使用readFile()读取文件,再使用writeFile()写入。
获取文件信息
fs.stat(path,callback);
//callback:回调函数,两个参数,err,stats(是fs.stats对象)
stats类函数说明
函数 | 说明 |
---|---|
stats.isFile() | 是文件返回true,否则返回false |
stats.isDirectory() | 是目录返回true,否则返回false |
stats.isBlockDevice() | 是块设备返回true,否则返回false |
stats.isCharacterDevice() | 是字符设备返回true,否则返回false |
stats.isSymbolicLink() | 是软链接返回true,否则返回false |
stats.isFIFO() | 是FIFO返回true,否则返回false。FIFO是UNIX中的一种特殊类型的命令管道 |
stats.isSocket() | 是Socket返回true,否则返回false |
路径字符串操作(Path模块)
加载模块:
var path= require('path');
函数 | 说明 |
---|---|
basename(p) | 获取文件名 |
dirname(p) | 获取文件目录 |
extname(p) | 获取文件扩展名 |
isAbsolute(path) | 判断是否是绝对路径 |
join(path1[,path2,...]); | 拼接路径字符串 |
normalize(p) | 将非标准路径转换为标准路径 |
sep | 获取操作系统的文件路径分隔符 |
目录操作
创建目录
fs.mkdir(path[,mode],callback);
//mode:设置目录权限,默认为0777
//callback:回调函数
读取目录
fs.readdir(path,callback);
//callback有两个参数,err为错误信息,files为目录下的文件数组列表。
删除目录
fs.rmdir(path,callback);
删除目录时,该目录必须为空。
删除文件
fs.unlink(path,callback)
二进制:用0和1两个数码来表示的数据,基数为2,进位规则是“逢二进一”,借位规则是“借一当二”。
Node.js中的Buffer缓冲区模块是全局的,在使用时不需要使用require()函数来加载。
Buffer类:在内存中创建一个专门存放二进制数据的缓冲区。
Buffer()构造函数用于创建Buffer对象
//使用Buffer自己创建一个内存空间,单位为字节
var buf=new Buffer(size);
//传入数组的方式创建Buffer实例
var buf=new Buffer([10,20,30]);
//传入字符串和编码
var buf=new Buffer("hello","utf-8");
//Buffer和JavaScript字符串对象之间的转换需要显示地调用编码方式完成
写入缓冲区
buf.write(string[,offset[,length]][,encoding]);
//offset:缓冲区开始写入的索引值,默认为0
//length:写入的字节数,默认为buffer.length
//encoding:使用的编码,默认为“utf-8”
从缓冲区读取数据
buf.toString([encoding[,start[,end]]]);
//将解码缓冲区数据并使用指定的编码返回字符串
//encoding:使用的编码,默认为“utf-8”
//start:指定开始读取的索引位置,默认为0
//end:结束位置,默认为缓冲区的末尾
拼接缓冲区
buf.concat(list[,totalLength]);
//返回一个多个成员合并的新Buffer对象。
var buf=new Buffer('坚持');
var buf1=new Buffer('自律');
var buf2=Buffer.concat([buf,buf1]);
console.log(buf2.toString());
Stream文件流
Buffer缓冲区限制在1GB。Stream文件流模块,用来解决大数据文件操作的问题。
流的好处是接收方可以提前处理,缩短等待时间,提高速度。
Stream是一个抽象接口
Stream有四种流类型:
(1)Readable:可读流
(2)Writable:可写流
(3)Duplex:可读可写操作,双向流,双工流
(4)Transform:变换流,操作被写入数据,然后读出结果。
所有的Stream对象都是EventEmitter(时间触发器)的实例
Stream常用事件:
事件 | 说明 |
---|---|
data | 当有数据可读时触发 |
end | 没有更多得到数据可读时触发 |
error | 在接收和写入过程中发生错误时触发 |
finish | 所有数据已被写入到底层系统时触发 |
可读流:让用户在源文件中分块读取文件中的数据,然后再从可读流中读取数据。
var fs=require('fs');
var readableStream=fs.createReadStream(path[,options]);
readableStream.setEncoding('UTF8');
流事件的操作都是异步的。
可写流:
fs.createWriteStream(path[,options]);
var fs= require('fs');
var readableStream=fs.createReadStream('L.txt');
var writeableStream=fs.createWriteStream('xx.txt');
readableStream.setEncoding('utf8');
readableStream.on('data',function(chunk){
writeableStream.write(chunk);
});
使用pipe()处理大文件
readableStream.pipe(writableStream)
IP地址:用来定位一台计算机,通过IP地址找到服务器设备。
端口号:在发送数据时定位到不同服务器应用程序的标识。一个端口号只能被一个应用程序占用。
TCP:传输控制协议,是一种稳定可靠的传送方式。
Socket是支持TCP/IP的网络通信的基本操作单元。是对TCP/IP协议的封装,Socket本身不是协议,而是一个调用接口(API)。
Node.js中的套接字服务由Net模块提供
引入模块
var net = require('net');
创建TCP或本地服务器
var server = net.createServer();
server对象的事件
事件 | 描述 |
---|---|
listening | 当服务器调用server.listen绑定后会触发 |
connection | 当新连接创建后会触发 |
close | 服务器关闭时会触发 |
error | 发生错误时触发 |
创建客户端
net.createConnection({
port:xx
});
Process模块获取终端输入
Process模块无需使用require()引入,是一个全局对象。
获取进程中输入的数据(终端的输入数据)
process.stdin.on('data',function(data){
console.log(data.toString().trim());
});
HTTP:超文本传输协议,基于TCP的连接方式。
加载HTTP模块
var http=require('http');
创建http.Server对象
var server=http.createServer();