util模块的使用

格式化输出字符串

util 模块提供了 format() 方法,用来对字符串进行格式化,其语法格式如下:

util.format(format, [...])

参数 format 是包含零个或多个占位符的字符串,每个占位符都是以一个 % 字符开始,并最终被对应的参数转换的字符串值取代。format 方法支持的占位符有以下类型。

  • %s:指定字符串。

  • %d:指定数值。

  • %i:转换为整数。

  • %f:转换为小数。

  • %j:转换为 JSON 字符串。

  • %o:转换为具有通用 JavaScript 对象格式的字符串表示形式,与 util.inspect() 类似,它显示了完整的对象以及不可枚举的属性。

  • %O:与 %o 相似,但没有选项,它不包含不可枚举的属性。

  • %%:输出 %

  • 返回值:格式化后的字符串。

下面通过一个示例演示以上部分占位符的使用。

【例6.1】使用 util 格式化字符串。(实例位置:资源包\源码\06\01)

代码如下:

const util=require("util")
function Person() {
     this.name = '老张';
     this.age=60;
     this.showName = function() {
          return this.name;
     };
}
var man = new Person();
console.log(util.format("%d+%d=%d",50,70,50+70))
console.log(util.format("整数:%i",26.01))
console.log(util.format("小数:%f","26.01"))
console.log(util.format("百分数:%d%%","26"))
console.log(util.format("对象格式化为JSON:%j",man))

运行结果如下:

50+70=120
整数:26
小数:26.01
百分数:26%
对象格式化为JSON:{"name":"老张","age":60}

将对象转换为字符串

util 模块提供了一个 inspect() 方法,用于将任意对象转换为字符串,该方法通常用于调试和错误输出,其语法格式如下:

util.inspect(object[, showHidden[, depth[, colors]]])

其中,参数 object 是必需的参数,用来指定一个对象;参数 showHiddentrue 时,将会显示更多的关于 object 对象的隐藏信息;参数 depth 表示最大递归层数,用于对象比较复杂时指定对象的递归层数;参数 colors 的值若为 true,表示输出格式将会以 ANSI 颜色编码,通常用于在终端上显示更漂亮的效果。

【例6.2】使用 inspect() 将对象转换为字符串。(实例位置:资源包\源码\06\02)

创建一个 Person 对象,并创建 Person 对象的实例 man,然后将 man 对象转换成字符串,代码如下:

const util=require("util")
function Person() {
     this.name = '老张';
     this.age = 60;
     this.showName = function() {
          return this.name;
     };
}
var man = new Person();
console.log(util.inspect(man));
console.log(util.inspect(man, true));

运行结果如下:

Person { name: '老张', age: 60, showName: [Function (anonymous)] }
Person {
     name: '老张',
     age: 60,
     showName: <ref *1> [Function (anonymous)] {
          [length]: 0,
          [name]: '',
          [arguments]: null,
          [caller]: null,
          [prototype]: { [constructor]: [Circular *1] }
     }
}

实现对象间的原型继承

util 模块提供了一个 inherits() 方法,用于实现对象间的原型继承,其语法格式如下:

util.inherits(constructor, superConstructor)

参数 constructor 表示要从原型继承的任何对象,参数 superConstructor 表示要继承的原型对象。

【例6.3】 使用 inherits() 实现对象间的原型继承。(实例位置:资源包\源码\06\03)

创建一个原型对象 par 和一个继承自 par 对象的 ch 对象。首先为 par 对象定义 3 个属性,并使用 prototype 定义一个方法;然后使用 util 模块的 inherits() 方法为 ch 对象实现 par 对象的原型继承。代码如下:

var util = require('util');
function par() {
     this.name = '老张';
     this.age = 60;
     this.say = function () {
          console.log(this.name + "今年" + this.age + "岁");
     };
}
par.prototype.showName = function () {
     console.log("我是" + this.name);
};
function ch() {
     this.name = '小张';
}
util.inherits(ch, par);
var objBase = new par();
objBase.showName();
objBase.say();
console.log(objBase);
var objSub = new ch();
objSub.showName();
console.log(objSub);

运行结果如下:

我是老张
老张今年60岁
par { name: '老张', age: 60, sayHello: [Function (anonymous)] }
我是小张
ch { name: '小张' }

通过上面的结果可以看出,ch 仅继承了 par 在原型中定义的函数,而构造函数内部的 age 属性、say 函数都没有被继承,这一点大家使用时要注意。

const util = require('util');

// 父类构造函数
function Animal(name) {
    this.name = name;
}

Animal.prototype.sayHello = function() {
    console.log(`Hello, I'm ${this.name}`);
};

// 子类构造函数
function Dog(name, breed) {
    Animal.call(this, name); // 调用父类构造函数
    this.breed = breed;
}

// 使用 util.inherits() 实现继承
util.inherits(Dog, Animal);

// 创建子类实例
const dog = new Dog('Buddy', 'Golden Retriever');

console.log(util.inspect(dog));

// 调用继承的父类方法
dog.sayHello(); // 输出: Hello, I'm Buddy
console.log(dog.breed); // 输出: Golden Retriever

Node.js 8.x 开始,util.inherits() 被认为是一个旧 API,虽然它仍然可以使用,但推荐使用 ES6class 语法来实现继承,class 更加现代和直观。

class Animal {
    constructor(name) {
        this.name = name;
    }

    sayHello() {
        console.log(`Hello, I'm ${this.name}`);
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name); // 调用父类构造函数
        this.breed = breed;
    }
}

const dog = new Dog('Buddy', 'Golden Retriever');
dog.sayHello(); // 输出: Hello, I'm Buddy
console.log(dog.breed); // 输出: Golden Retriever

转换异步函数的风格

util 模块中的 callbackify() 方法可以将 async 异步函数(或者一个返回值为 Promise 的函数)转换成遵循错误优先回调风格的函数,其语法格式如下:

util.callbackify(async_function)

参数 async_function 表示原始的 async 异步函数,该方法的返回值是一个以错误优先回调风格返回的 Promise 函数,基本形式为 (err,ret)=>{},第一个参数是错误原因。

例如,定义一个异步函数 fn,使用 util 模块的 callbackify() 对其进行风格转换,然后执行转换风格后的异步函数,其中传入一个错误优先风格的回调函数 function(err,ret)。代码如下:

const util = require('util');
async function fn() {
     return '这是一个函数';
}
const callbackFunction = util.callbackify(fn);
callbackFunction(function (err, ret) {
     if (err) throw err;
     console.log(ret);
});

运行结果如下:

这是一个函数

在定义的函数前面加 async 关键字,则该函数就会成为一个异步函数,关于异步函数的详细讲解,请参见第 9 章。

判断是否为指定类型的内置对象

除了上面常用的一些方法,util 模块中还提供了一个 types 类型,通过调用该类型的一些方法,可以为不同类型的内置对象提供类型检查。常用的类型检查方法如下。

  • util.types.isAnyArrayBuffer(value):判断 value 是否为内置的 ArrayBufferSharedArrayBuffer 实例。示例代码如下:

    const util = require('util')
    console.log(util.types.isAnyArrayBuffer(new ArrayBuffer()));
    console.log(util.types.isAnyArrayBuffer(new SharedArrayBuffer()));

    运行结果如下:

    true
    true
  • util.types.isArrayBufferView(value):判断 value 是否为 ArrayBuffer 视图的实例。示例代码如下:

    const util = require('util')
    console.log(util.types.isArrayBufferView(new Int8Array()));       //true
    console.log(util.types.isArrayBufferView(Buffer.from('你好')));   //true
    console.log(util.types.isArrayBufferView(new ArrayBuffer()));     //false

    运行结果如下:

    true
    true
    false
  • util.types.isArrayBuffer(value):判断 value 是否为内置的 ArrayBuffer 实例。示例代码如下:

    const util = require('util');
    console.log(util.types.isArrayBuffer(new ArrayBuffer()));        //true
    console.log(util.types.isArrayBuffer(new SharedArrayBuffer()));  //false

    运行结果如下:

    true
    false
  • util.types.isAsyncFunction(value):判断 value 是否为异步函数。示例代码如下:

    const util = require('util');
    console.log(util.types.isAsyncFunction(function func(){}));          //false
    console.log(util.types.isAsyncFunction(async  function func(){}));   //true

    运行结果如下:

    false
    true
  • util.types.isBooleanObject(value):判断 value 是否为布尔类型。示例代码如下:

    const util = require('util')
    console.log(util.types.isBooleanObject(false));               //false
    console.log(util.types.isBooleanObject("false"));             //false
    console.log(util.types.isBooleanObject(new Boolean(false)));  //true
    console.log(util.types.isBooleanObject(new Boolean(true)));   //true
    console.log(util.types.isBooleanObject(Boolean(false)));      //false

    运行结果如下:

    false
    false
    true
    true
    false
  • util.types.isBoxedPrimitive(value):判断 value 是否为原始对象,如 new Boolean()new String() 等。示例代码如下:

    const util = require('util')
    console.log(util.types.isBoxedPrimitive(new Boolean(false)));    //true
    console.log(util.types.isBoxedPrimitive(new String("string")));  //true
    console.log(util.types.isBoxedPrimitive("string"));              //false

    运行结果如下:

    true
    true
    false
  • util.types.isDate(value):判断 value 是否为 Date 的实例。示例代码如下:

    const util = require('util');
    console.log(util.types.isDate(new Date()));           //true
    console.log(util.types.isDate(new Date(2023,6,18)));  //true

    运行结果如下:

    true
    true
  • util.types.isNumberObject(value):判断 value 是否为 Number 对象。示例代码如下:

    const util = require('util');
    console.log(util.types.isNumberObject(0));              //false
    console.log(util.types.isNumberObject(new Number()));   //true
    console.log(util.types.isNumberObject(new Number(0)));  //true

    运行结果如下:

    false
    true
    true
  • util.types.isRegExp(value):判断 value 是否为一个正则表达式。示例代码如下:

    const util = require('util');
    console.log(util.types.isRegExp(/^\w+$/));            //true
    console.log(util.types.isRegExp(new RegExp('abc')));  //true

    运行结果如下:

    true
    true
  • util.types.isStringObject(value):判断 value 是否为一个 String 对象。示例代码如下:

    const util = require('util');
    console.log(util.types.isStringObject('string'));              //false
    console.log(util.types.isStringObject(new String('string')));  //true

    运行结果如下:

    false
    true
  1. 通过上面的示例代码和对应效果可以看出,util.types 中各方法的返回值都是布尔类型。

  2. 上面介绍的方法仅为 util.types 包含的常见方法,读者也可以在其官网说明手册中查看所有方法,官网网址是 http://nodejs.cn/api/util.html#util_util_types_isarraybufferview_value