util是Node.js的核心模塊拢军,提供了常用函數(shù)的集合,用于彌補(bǔ)核心JavaScript功能過(guò)于精簡(jiǎn)的不足送巡。util模塊設(shè)計(jì)的主要目的是為了滿(mǎn)足Node.js內(nèi)部API的需求摹菠。
const util = require("util");
Node.js的util模塊提供了實(shí)用函數(shù)來(lái)格式化字符串、將對(duì)象轉(zhuǎn)化為字符串骗爆、檢查對(duì)象類(lèi)型次氨、執(zhí)行對(duì)輸出流的同步寫(xiě)入,以及對(duì)對(duì)象繼承的增強(qiáng)摘投。
格式化字符串format
在處理字符串時(shí)通常需要快速格式化字符串煮寡,Node.js在util模塊中提供了一個(gè)基本的字符串格式化方法用于處理字符串格式化的需求虹蓄。
util.format(format, [...])
util.form()函數(shù)接收 一個(gè)格式化字符串format作為第一個(gè)參數(shù),并返回格式化后的字符串幸撕。
format參數(shù)是可用包含零個(gè)或多個(gè)占位符的字符串薇组,每個(gè)占位符都是以一個(gè)%字符開(kāi)始,并最終被對(duì)應(yīng)的參數(shù)轉(zhuǎn)換的字符串值取代坐儿。
占位符 | 描述 |
---|---|
%s | 指定字符串 |
%d | 指定數(shù)值 |
%j | 指定JSON可轉(zhuǎn)化為字符串的對(duì)象 |
%o | Object律胀,包括不可枚舉的屬性。 |
%O | Object貌矿,不包括不可枚舉的屬性炭菌。 |
% | 若%后保留為空則不作為占位符 |
%% | 輸出% |
使用format函數(shù)時(shí)需要注意
- 若參數(shù)沒(méi)有占位符多則多余占位符都不會(huì)被替換
console.log(util.format("%s = %s", "alice"));//alice = %s
- 當(dāng)有比占位符更多的參數(shù)時(shí)多余的參數(shù)會(huì)被轉(zhuǎn)換為字符串,然后以空格分隔符連接逛漫。
console.log(util.format("%s = %s", "name", "alice", 18));//name = alice 18
- 若第一個(gè)參數(shù)不是格式化字符串黑低,則會(huì)將每個(gè)參數(shù)都轉(zhuǎn)換為字符串,并使用空格分隔符將其連接酌毡,返回連接后的字符串投储。
console.log(util.format(1,2,3));//1 2 3
對(duì)象轉(zhuǎn)字符串inspect
util.inspect(object, [showHidden], [depth], [colors])
util.inspect(object[, options])
inspect是將任意對(duì)象轉(zhuǎn)化為字符串的方法,用于調(diào)試和錯(cuò)誤輸出阔馋。它至少接受一個(gè)參數(shù)object即需要轉(zhuǎn)換的對(duì)象。
function Klass(){
this.name = "alice";
this.toString = function(){
return this.name;
}
}
const obj = new Klass();
console.log(util.inspect(obj));//Klass { name: 'alice', toString: [Function] }
參數(shù) | 描述 |
---|---|
object | 需要轉(zhuǎn)換的對(duì)象 |
showHidden | 可選娇掏,表示是否枚舉顯式對(duì)象的隱藏屬性呕寝,默認(rèn)false,若為true則輸出更多隱藏信息婴梧。 |
depth | 可選下梢,表示最大遞歸層數(shù)即設(shè)置對(duì)象枚舉顯式的深度,默認(rèn)為2塞蹭。若指定為null表示不限遞歸層數(shù)完整遍歷孽江。 |
colors | 可選,colors為true表示輸出格式會(huì)以ANSI顏色編碼番电,用于終端顯式岗屏。 |
例如:對(duì)象轉(zhuǎn)字符串并顯式隱藏信息
console.log(util.inspect(obj, true));
Klass {
name: 'alice',
toString:
{ [Function]
[length]: 0,
[name]: '',
[arguments]: null,
[caller]: null,
[prototype]: { [constructor]: [Circular] } } }
例如:JSON對(duì)象轉(zhuǎn)字符串
const obj = {id:1, name:"alice"}
console.log(util.inspect(obj, true));//{ id: 1, name: 'alice' }
同步寫(xiě)入輸出流
util模塊具有同步寫(xiě)數(shù)據(jù)到標(biāo)準(zhǔn)輸入stdout和標(biāo)準(zhǔn)錯(cuò)誤stderr的能力,意味著進(jìn)程會(huì)保持阻塞直到數(shù)據(jù)被寫(xiě)出來(lái)為止漱办≌馑ⅲ可用于確保當(dāng)前數(shù)據(jù)被寫(xiě)入時(shí),系統(tǒng)并沒(méi)有改變其行為娩井。
函數(shù) | 描述 |
---|---|
util.debug(string) | 將字符串寫(xiě)入到標(biāo)準(zhǔn)錯(cuò)誤stderr中暇屋,已過(guò)時(shí)使用console.error()替代。 |
util.error([...]) | 接受多個(gè)參數(shù)將其寫(xiě)入到標(biāo)準(zhǔn)錯(cuò)誤stderr中洞辣,已過(guò)時(shí)使用console.error()替代咐刨。 |
util.puts([...]) | 接受多個(gè)參數(shù)將其寫(xiě)入到標(biāo)準(zhǔn)輸出stdout中昙衅,已過(guò)時(shí)使用console.log()替代。 |
util.print([...]) | 接受多個(gè)參數(shù)將其轉(zhuǎn)換為字符串后寫(xiě)入到標(biāo)準(zhǔn)輸出stdout中定鸟,已過(guò)時(shí)使用console.log()替代而涉。 |
util.log(string) | 將字符串以及時(shí)間戳寫(xiě)入到標(biāo)準(zhǔn)輸出stdout中 |
控制臺(tái)標(biāo)準(zhǔn)輸出util.log
util.log(string)
log方法用于在控制臺(tái)標(biāo)準(zhǔn)輸出stdout,輸出時(shí)會(huì)帶有時(shí)間戳仔粥。
util.log("hello world");//21 Dec 12:42:07 - hello world
調(diào)試輸出util.debuglog
util.debuglog(section)
debuglog方法用于根據(jù)NODE_DEBUG環(huán)境變量來(lái)選擇性的輸出debug信息婴谱。
檢查對(duì)象類(lèi)型
判斷對(duì)象類(lèi)型最常用的方式是使用instanceof運(yùn)算符,util模塊提供了常用的便捷函數(shù)躯泰。
console.log([] instanceof Array);//true
判斷函數(shù) | 描述 |
---|---|
util.isArray(object) | 判斷給定對(duì)象是否為數(shù)組 |
util.isDate(object) | 判斷給定對(duì)象是否為日期 |
util.isRegExp(object) | 判斷給定對(duì)象是否為正則 |
util.isError(object) | 判斷給定對(duì)象是否為錯(cuò)誤 |
檢查對(duì)象是否為數(shù)組util.isArray
util.isArray(object)
isArray方法用于檢查傳入對(duì)象object是否為數(shù)組谭羔,返回布爾值,是為true否為false麦向。
console.log(util.isArray([]));//true
console.log(util.isArray(new Array));//true
console.log(util.isArray({}));//false
檢查對(duì)象是否為Date類(lèi)型util.isDate
util.isDate(object)
isDate方法用于檢查傳入的對(duì)象object是否為Date日期類(lèi)型瘟裸,返回布爾值,是為true否為false诵竭。
console.log(util.isDate({}));//false
console.log(util.isDate(new Date()));//true
console.log(util.isDate(Date()));//false
檢查對(duì)象是否為Error類(lèi)型util.isError
util.isError(object)
isError方法用于檢查對(duì)象是否為Error類(lèi)型话告,返回布爾值,是為true否為false卵慰。
console.log( util.isError({name:"Error", message:"an error occurred"}) );//false
console.log( util.isError(new Error()) );//true
console.log( util.isError(new TypeError()) );//true
檢查對(duì)象是否為正則表達(dá)式util.isRegExp
util.isRegExp(object)
isRegExp方法用于檢查給定對(duì)象objet是否為RegExp正則表達(dá)式沙郭,返回布爾值,是為true否為false裳朋。
console.log( util.isRegExp({}) );//false
console.log( util.isRegExp(/regexp rule/) );//true
console.log( util.isRegExp(new RegExp("pattern")) );//true
對(duì)象原型繼承util.inherits
inherits方法用于實(shí)現(xiàn)對(duì)象之間的原型繼承病线,JavaScript面向?qū)ο筇匦允腔谠偷模c基于類(lèi)不同鲤嫡。JavaScript中沒(méi)有提供對(duì)象繼承的語(yǔ)言級(jí)別特性送挑,是通過(guò)原型復(fù)制來(lái)實(shí)現(xiàn)。
util.inherits(constructor, superConstructor)
inherits方法允許創(chuàng)建一個(gè)繼承自另一個(gè)對(duì)象prototype原型方法的對(duì)象暖眼。當(dāng)創(chuàng)建新對(duì)象時(shí)prototype原型方法會(huì)自動(dòng)被使用惕耕。
const util = require("util");
//父類(lèi)
function Base(opts){
//父類(lèi)私有屬性
this.id = opts.id || 0;
this.name = opts.name || "";
//父類(lèi)私有方法
this.output = function(){
console.log(this.id, this.name);
};
}
//父類(lèi)原型方法
Base.prototype.getName = function(){
return this.name;
};
//子類(lèi)
function Sub(opts){
//子類(lèi)繼承父類(lèi)屬性
Base.call(this, opts)
//子類(lèi)屬性覆寫(xiě)父類(lèi)屬性
this.name = "subname";
//子類(lèi)新增私有屬性
this.type = opts.type||"";
}
//子類(lèi)原型繼承
util.inherits(Sub, Base);
//創(chuàng)建子類(lèi)對(duì)象
const sub = new Sub({id:1, type:"subtype"});
console.log(sub);//Sub { id: 1, name: 'subname', output: [Function], type: 'subtype' }
//子類(lèi)繼承父類(lèi)原型方法
console.log(sub.getName());//subname
在新對(duì)象被創(chuàng)建時(shí)會(huì)執(zhí)行原型constructor設(shè)定為原型superConstructor,可使用constructor.super_
屬性從自定義對(duì)象的構(gòu)造函數(shù)中訪問(wèn)父類(lèi)構(gòu)造函數(shù)superConstructor诫肠。
例如:使用inherits方法繼承events.EventEmitter事件觸發(fā)器對(duì)象的構(gòu)造函數(shù)來(lái)創(chuàng)建一個(gè)Writable寫(xiě)入流
const util = require("util");
const EventEmitter = require("events").EventEmitter;
//定義類(lèi)
function Writer(){
EventEmitter.call(this);
}
//類(lèi)的繼承
util.inherits(Writer, EventEmitter);
//自定義寫(xiě)入方法并調(diào)用父類(lèi)觸發(fā)方法
Writer.prototype.write = function(data){
this.emit("data", data);
};
//實(shí)例化對(duì)象
const writer = new Writer();
//判斷對(duì)象是否為繼承自父類(lèi)
console.log(writer instanceof EventEmitter);//true
//為writer注冊(cè)data事件
writer.on("data", function(data){
console.log("receive data:", data);//receive data: hello world
});
//寫(xiě)入數(shù)據(jù)并觸發(fā)data事件
writer.write("hello world");
console.log(writer);
Writer {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined }
風(fēng)格轉(zhuǎn)換util.promisify
Node.js的回調(diào)函數(shù)根據(jù)約定具有統(tǒng)一的形式司澎,即(error, value) => {}
。因此可將這種回調(diào)函數(shù)作為參數(shù)的函數(shù)轉(zhuǎn)化為返回Promise的函數(shù)区赵。
例如:結(jié)合async/await使用util.promisify異步讀取文件內(nèi)容
const util = require("util");
const fs = require("fs");
const asyncReadFile = util.promisify(fs.readFile);
async function main(file, charset = "utf-8"){
const content = await asyncReadFile(file, charset);
//console.log(content);
return content;
}
main("./README.md").then(data=>{
console.log(data);
});
例如:獲取文件夾統(tǒng)計(jì)信息
const util = require("util");
const fs = require("fs");
const stats = util.promisify(fs.stat);
async function main(dirname){
const content = await stats(dirname);
//console.log(content);
return content;
}
main(".").then(data=>{
console.log(data);
}).catch(error=>{
console.log(error);
});
Stats {
dev: 1650279073,
mode: 16822,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: undefined,
ino: 9007199255333340,
size: 0,
blocks: undefined,
atimeMs: 1576835786059.209,
mtimeMs: 1576835772463.417,
ctimeMs: 1576835772463.417,
birthtimeMs: 1576232793857.817,
atime: 2019-12-20T09:56:26.059Z,
mtime: 2019-12-20T09:56:12.463Z,
ctime: 2019-12-20T09:56:12.463Z,
birthtime: 2019-12-13T10:26:33.858Z }