深入理解Nodejs Global 模块
浏览器上有自己的全局对象window,同理,nodejs下也有自己的全局对象global,并且在各个模块下都可以直接访问global对象。
在nodejs中,除了可以直接使用V8JavaScript引擎中所支持的原生JavaScript的函数和对象外,它还追加了一些其他的函数和对象(比如:Buffer对象、require函数等)。
- Buffer对象:用于处理二进制数据
- module对象:用于访问当前模块的信息
- process对象:用于访问进程信息
- console对象:用于向控制端输出某些信息
- 6个计时器相关函数
需要注意的是,可以在不引入模块的情况下直接使用nodejs追加的这些函数和对象。
下面将对上面的这些对象和函数的使用进行简单的解释。
Buffer对象
在ES6之前,原生的JavaScript并没有专门用来处理二进制数据的机制,所以为了方便地处理二进制数据,nodejs才引入了Buffer对象。
ES6之后,原生的JavaScript引入了TypedArray,用来处理二进制数据。注意TypedArray并不是以一个单一的对象的形式而存在,而是以一系列值的类型为TypedArray的对象而存在。在这一系列对象中,Uint8Array对象和Buffer对象最为相似,但是Buffer对象更加适用于nodejs。
Buffer对象的实例很像一个各个元素都是整数的数组,但是与真正的数组的区别在于它的大小固定的(即在实例创建时决定大小),并且为它分配的内存是原生的,并且存在于V8的堆内存外。
在nodejs6.0版本之前,是使用newBuffer()语法来创建一个实例,但是因为一些安全问题,以这种形式创建实例的方法被废除了,取而代之的是一些Buffer对象的一些静态方法。
创建Buffer实例
- Buffer.alloc(size[,fill[,encoding]]):返回一个指定大小的Buffer实例,如果没有设置fill,则默认填满0
- Buffer.allocUnsafe(size):返回一个指定大小的Buffer实例,但是它不会被初始化,所以它可能包含敏感的数据
- Buffer.allocUnsafeSlow(size)
- Buffer.from(array):返回一个被array的值初始化的新的Buffer实例(传入的array的元素只能是数字,不然就会自动被0覆盖)
- Buffer.from(arrayBuffer[,byteOffset[,length]]):ThiscreatesaviewoftheArrayBufferwithoutcopyingtheunderlyingmemory
- Buffer.from(buffer):复制传入的Buffer实例的数据,并返回一个新的Buffer实例
- Buffer.from(string[,encoding]):返回一个被string的值初始化的新的Buffer实例
constbuf1=Buffer.alloc(5); constbuf2=Buffer.allocUnsafe(5); constbuf3=Buffer.from([1,'2a',230]); constbuf4=Buffer.from('abcdggg'); console.log(buf1);//console.log(buf2);// (这只是一种可能的结果) console.log(buf3);// console.log(buf4);// console.log(buf4.toString());//abcdggg buf2.fill(0); console.log(buf2);//
上面讲的不太清楚(以后再优化),因为我是初学,TypedArray都没玩过呢!
但是放心,大腿在这呢—Node源码解析–buffer
源码链接:buffer.js
Buffer.byteLength(string[,encoding]):返回string的实际的字节长度(注意不是字符长度)
letstr1='a'; letstr2='小'; letstr3='aa'; letstr4='小a'; console.log(str1.length);//1 console.log(Buffer.byteLength(str1));//1 console.log(str2.length);//1 console.log(Buffer.byteLength(str2));//3 console.log(str3.length);//2 console.log(Buffer.byteLength(str3));//2 console.log(str4.length);//2 console.log(Buffer.byteLength(str4));//4
上面的汉字小的UTF-8码正好占用三个字节(\xE5\xB0\x8F),所以才会有上面的结果。
Buffer.concat(list[,totalLength]):连接多个Buffer实例或Uint8Array实例,并返回一个新的Buffer实例
constbuf1=Buffer.alloc(10); constbuf2=Buffer.alloc(14); consttotalLength=buf1.length+buf2.length; console.log(totalLength);//24 constbuf=Buffer.concat([buf1,buf2],totalLength); console.log(buf.length);//24
Buffer.isBuffer(obj):判断一个对象是不是Buffer实例
Buffer.isEncoding(encoding):判断是否支持指定的编码方式
console.log(Buffer.isEncoding('utf8'));//true console.log(Buffer.isEncoding('utf9'));//false
Buffer.poolSize:指定预分配的字节数的大小,默认为8192(即8KB)
Buffer.prototype.buffer:一个指向ArrayBuffer的引用
constarrayBuffer=newArrayBuffer(16); constbuffer=Buffer.from(arrayBuffer); console.log(buffer.buffer===arrayBuffer);//true
Buffer.prototype.equals(otherBuffer):比较两个Buffer实例是否拥有完全相同的bytes
constbuf1=Buffer.from('hello'); constbuf2=Buffer.from('hello'); console.log(buf1.equals(buf2));//true
用于迭代的方法
- Buffer.prototype.entries()
- Buffer.prototype.keys()
- Buffer.prototype.values()
Buffer.prototype.fill(value[,offset[,end]][,encoding]):用指定的值填充满Buffer实例
constb=Buffer.allocUnsafe(25).fill('abc呵呵'); //注意下面因为不够容纳全部的汉字字节,所以乱码 console.log(b.toString());//abc呵呵abc呵呵abc呵�
Buffer.prototype.includes(value[,byteOffset][,encoding])
Buffer.prototype.indexOf(value[,byteOffset][,encoding])
Buffer.prototype.toJSON():返回一个JSON对象
当JSON.stringify(buf)的参数为一个Buffer实例时,会隐式地调用上面的方法
constb=Buffer.from('hell') letjson=b.toJSON(); console.log(json);//{type:'Buffer',data:[104,101,108,108]} console.log(JSON.stringify(b));//{"type":"Buffer","data":[104,101,108,108]}
Buffer.prototype.toString([encoding[,start[,end]]]):以指定的encoding解码Buffer实例,返回解码后的字符串
constbuf=Buffer.from([104,101,108,108]); console.log(buf.toString());//hell console.log(buf.toString('base64'));//aGVsbA== console.log(buf.toString('hex'));//68656c6c
字符串不能被修改,但是Buffer实例却可以被修改。
constbuf=Buffer.from('abcd'); console.log(buf.toString());//abcd buf[1]=122; console.log(buf.toString());//azcd
Buffer.prototype.write(string[,offset[,length]][,encoding]):将指定字符串写入到Buffer中
constbuf=Buffer.from('abcdefg'); console.log(buf);//console.log(buf.toString());//abcdefg buf.write('和',1); console.log(buf);// console.log(buf.toString());//a和efg
好了,还有一堆方法就不一一列出来了,Buffer就到这里了。
module对象
在使用require函数加载模块文件时,将运行该模块文件中的每一行代码
模块在首次加载后将缓存在内存缓存区中,所以对于相同模块的多次引用得到的都是同一个模块对象,即对于相同模块的多次引用不会引起该模块内代码的多次执行。
在编译的过程中,Node会对获取的JavaScript文件内容进行头尾包装!
//包装前module666.js constPI=6666; module.exports=PI; //包装后,注意下面不是立即执行函数 (function(exports,require,module,__filename,__dirname){ constPI=6666; module.exports=PI; });
__filename&__dirname
- __filename:返回当前模块文件的绝对路径(带文件名)
- __dirname:返回当前模块文件所在目录的绝对路径
//1.js console.log(__filename);//c:\Users\percy\Desktop\nodejs\1.js console.log(__dirname);//c:\Users\percy\Desktop\nodejs
Process对象
process对象是nodejs的一个全局对象,提供当前nodejs进程的信息。
属性
- process.arch:返回当前处理器的架构
- process.env:返回一个包含用户环境变量的对象
- process.argv:返回一个数组,数组的第一个元素总是node程序的绝对路径,第二个元素是当前执行脚本的绝对路径
- process.execPath:返回node程序的绝对路径
- process.argv0:返回node程序的绝对路径
- process.pid:返回当前进程的进程号
- process.platform:返回当前的系统平台标识符(比如:'darwin',‘freebsd',‘linux',‘sunos'or‘win32')
- process.version:返回当前node的版本号
- process.versions:返回一个对象,列出了nodejs和其相关依赖的版本号
三个重要的属性
- process.stdin:返回一个指向标准输入流的可读流(ReadableStream)
- process.stdout:返回一个指向标准输出流的可写流(WritableStream)
- process.stderr:返回一个指向标准错误流的可写流(WritableStream)
方法
- process.cwd():返回进程当前的工作目录
- process.chdir(path):改变进程当前的工作目录
- process.cpuUsage():返回当前CPU的使用情况
- process.memoryUsage():返回当前内存的使用情况
- process.uptime():返回Node程序已运行的秒数
- process.nextTick(callback[,…args]):指定回调函数在当前执行栈的尾部、下一次EventLoop之前执行
- process.emitWarning(warning[,options]):触发一个warning事件,可以自定义一些警告信息
- process.exit([code]):立即结束当前进程,但是会触发process的exit事件
- process.abort():立即结束当前进程,不会触发exit事件
console.log(process.cwd());//c:\Users\percy\Desktop\nodejs process.chdir('../'); console.log(process.cwd());//c:\Users\percy\Desktop
process.emitWarning('Somethinghappened!',{ code:'MY_WARNING', detail:'Thisissomeadditionalinformation' }); process.on('warning',(warning)=>{ console.log(warning); })
process.on('exit',function(code){ console.log('exit~',code); }); process.exit();//exit~
process对象还有一些方法没列出来,因为我现在看不懂怎么用,以后补>_<
Console对象
这个对象就是用来在控制台下面打印一些信息而已,挑几个有用但没记牢的方法来玩玩。
console.dir(value):打印一个对象的详细信息
constbuf=Buffer.from('abcdefg'); console.log(buf);//console.dir(buf);//Buffer[97,98,99,100,101,102,103]
console.time(label)&console.timeEnd(label):用来统计代码执行时间
letlabel='time'; letstr='hello'; console.time(label); while(str.length<999999){ str+='a'; } console.timeEnd(label);//time:133.724ms
6个计时器函数
在浏览器上,就有相应的4个计时器函数(setInterval、clearInterval、setTimeout、clearTimeout),只不过它们是window全局对象的属性。
在nodejs中,除过上面的4个计时器,还增加了两个(setImmediate,clearImmediate)。
这六个计时器函数被定义在了全局对象global下,即可以直接在代码中进行使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。