背景

近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓

方法总览

Map / WeakMap / Set / WeakSet

这四个是 JavaScript/TypeScript 的标准容器类型,TypeUtil 分别提供了对应的检测方法:

// Map 检测
this.Btn('isMap(new Map()) → true', '#16A085', () => {
  this.addLog(`isMap(new Map()) → ${TypeUtil.isMap(new Map())}`);
})
this.Btn('isMap({}) → false', '#16A085', () => {
  const obj: SampleObj = { a: 0 };
  this.addLog(`isMap({}) → ${TypeUtil.isMap(obj)}`);
})

// WeakMap 检测
this.Btn('isWeakMap(new WeakMap()) → true', '#1ABC9C', () => {
  this.addLog(`isWeakMap(new WeakMap()) → ${TypeUtil.isWeakMap(new WeakMap())}`);
})

// Set 检测
this.Btn('isSet(new Set([1,2])) → true', '#2ECC71', () => {
  this.addLog(`isSet(new Set([1,2])) → ${TypeUtil.isSet(new Set([1, 2]))}`);
})

// WeakSet 检测
this.Btn('isWeakSet(new WeakSet()) → true', '#27AE60', () => {
  this.addLog(`isWeakSet(new WeakSet()) → ${TypeUtil.isWeakSet(new WeakSet())}`);
})

运行结果:

isMap(new Map()) → true
isMap({}) → false
isWeakMap(new WeakMap()) → true
isSet(new Set([1,2])) → true
isWeakSet(new WeakSet()) → true

实际使用场景:

接受通用参数的函数,需要判断传入的是 Map 还是普通对象 {}

function processData(data: Map<string, number> | Record<string, number>) {
  if (TypeUtil.isMap(data)) {
    // 按 Map 处理
    data.forEach((v, k) => console.log(k, v));
  } else {
    // 按对象处理
    Object.entries(data).forEach(([k, v]) => console.log(k, v));
  }
}

Date / RegExp / DataView

// Date 检测
this.Btn('isDate(new Date()) → true', '#F39C12', () => {
  this.addLog(`isDate(new Date()) → ${TypeUtil.isDate(new Date())}`);
})
this.Btn('isDate("2024-01-01") → false', '#F39C12', () => {
  this.addLog(`isDate("2024-01-01") → ${TypeUtil.isDate("2024-01-01")}`);
})

// RegExp 检测
this.Btn('isRegExp(/abc/g) → true', '#E67E22', () => {
  this.addLog(`isRegExp(/abc/g) → ${TypeUtil.isRegExp(/abc/g)}`);
})

// DataView 检测
this.Btn('isDataView(new DataView(buf)) → true', '#D35400', () => {
  const buf = new ArrayBuffer(8);
  const dv = new DataView(buf);
  this.addLog(`isDataView(new DataView(buf)) → ${TypeUtil.isDataView(dv)}`);
})

运行结果:

isDate(new Date()) → true
isDate("2024-01-01") → false
isRegExp(/abc/g) → true
isDataView(new DataView(buf)) → true

isDate("2024-01-01") 返回 false 这个很重要——字符串日期不是 Date 对象,不能直接调 .getFullYear() 等方法。

ArrayBuffer 系列

// ArrayBuffer 检测
this.Btn('isArrayBuffer(new ArrayBuffer(4)) → true', '#2C3E50', () => {
  this.addLog(`isArrayBuffer(new ArrayBuffer(4)) → ${TypeUtil.isArrayBuffer(new ArrayBuffer(4))}`);
})

// AnyArrayBuffer(包含 SharedArrayBuffer)
this.Btn('isAnyArrayBuffer(new ArrayBuffer(4)) → true', '#2C3E50', () => {
  this.addLog(`isAnyArrayBuffer(new ArrayBuffer(4)) → ${TypeUtil.isAnyArrayBuffer(new ArrayBuffer(4))}`);
})

运行结果:

isArrayBuffer(new ArrayBuffer(4)) → true
isAnyArrayBuffer(new ArrayBuffer(4)) → true

isArrayBuffer 只检测 ArrayBufferisAnyArrayBuffer 还包含 SharedArrayBuffer(共享内存缓冲区)。

TypedArray 系列(Uint8Array、Int32Array 等)

TypedArray 是一系列类型化数组视图,常用于二进制数据处理、网络传输、图像处理等场景:

// Uint8Array(无符号8位,常用于字节数组)
this.Btn('isUint8Array(new Uint8Array()) → true', '#34495E', () => {
  this.addLog(`isUint8Array(new Uint8Array()) → ${TypeUtil.isUint8Array(new Uint8Array())}`);
})

// Uint16Array(无符号16位)
this.Btn('isUint16Array(new Uint16Array()) → true', '#34495E', () => {
  this.addLog(`isUint16Array(new Uint16Array()) → ${TypeUtil.isUint16Array(new Uint16Array())}`);
})

// Uint32Array(无符号32位)
this.Btn('isUint32Array(new Uint32Array()) → true', '#34495E', () => {
  this.addLog(`isUint32Array(new Uint32Array()) → ${TypeUtil.isUint32Array(new Uint32Array())}`);
})

// Int8Array(有符号8位)
this.Btn('isInt8Array(new Int8Array()) → true', '#7F8C8D', () => {
  this.addLog(`isInt8Array(new Int8Array()) → ${TypeUtil.isInt8Array(new Int8Array())}`);
})

// Int16Array(有符号16位)
this.Btn('isInt16Array(new Int16Array()) → true', '#7F8C8D', () => {
  this.addLog(`isInt16Array(new Int16Array()) → ${TypeUtil.isInt16Array(new Int16Array())}`);
})

// Int32Array(有符号32位)
this.Btn('isInt32Array(new Int32Array()) → true', '#7F8C8D', () => {
  this.addLog(`isInt32Array(new Int32Array()) → ${TypeUtil.isInt32Array(new Int32Array())}`);
})

// 泛型判断:是否是任意 TypedArray
this.Btn('isTypedArray(new Float32Array()) → true', '#626567', () => {
  this.addLog(`isTypedArray(new Float32Array()) → ${TypeUtil.isTypedArray(new Float32Array())}`);
})

运行结果:

isUint8Array(new Uint8Array()) → true
isUint16Array(new Uint16Array()) → true
isUint32Array(new Uint32Array()) → true
isInt8Array(new Int8Array()) → true
isInt16Array(new Int16Array()) → true
isInt32Array(new Int32Array()) → true
isTypedArray(new Float32Array()) → true

TypedArray 类型速查:

类型 范围 常用场景
Uint8Array 0~255 字节流、图片数据、网络包
Uint16Array 0~65535 音频采样、字符编码
Uint32Array 0~4294967295 像素数据(RGBA)、哈希
Int8Array -128~127 有符号字节数据
Int16Array -32768~32767 音频PCM
Int32Array -231~231-1 整型缓冲区
Float32Array 32位浮点 WebGL/图形计算

如果你只想知道"这是不是某种TypedArray",不在乎具体是哪种,用 isTypedArray() 最简单。

实际使用示例

处理二进制数据时,经常需要判断传入的是哪种类型:

function handleBinaryData(data: Uint8Array | ArrayBuffer) {
  if (TypeUtil.isUint8Array(data)) {
    // 直接用字节视图处理
    for (let i = 0; i < data.length; i++) {
      console.log(data[i]);
    }
  } else if (TypeUtil.isArrayBuffer(data)) {
    // 先包装成视图
    const view = new Uint8Array(data);
    // ... 处理
  }
}

写在最后

容器类型和特殊对象的判断,用 TypeUtil 比自己写 instanceof 或者 Object.prototype.toString.call() 方便太多了。

记住最常用的几个:

  • 容器:isMapisSet
  • 时间:isDate(别用字符串当Date用)
  • 正则:isRegExp
  • 二进制:isArrayBufferisUint8ArrayisTypedArray

更多推荐