# 类型判断
# 题目
实现一个 getType 函数,传入一个变量,能准确的获取它的类型。
如 number string function object array map regexp 等。
# 类型判断
常规的类型判断一般用 typeof 和 instanceof ,但这俩也有一些缺点
typeof无法继续区分object类型instanceof需要知道构造函数,即需要两个输入
# 枚举不是好方法
你可能觉得 typeof 和 instanceof 结合起来可以判断,枚举所有的类型。
这并不是一个好方法,因为手动枚举是不靠谱的,不具备完整性。
第一,你有可能忽略某些类型,如;第二,ES 有会继续增加新的类型,如 Symbol BigInt
function getType(x: any): string {
if (typeof x === 'object') {
if (Array.isArray(x)) return 'array'
if (x instance of Map) return 'map'
// 继续枚举...
}
return typeof x
}
# 使用 Object.prototype.toString
注意,必须用 Object.prototype.toString ,不可以直接用 toString。后者可能是子类重写的。
[1, 2].toString() // '1,2' ( 这样使用的其实是 Array.prototype.toString )
Object.prototype.toString.call([1, 2]) // '[object Array]'
/**
* 获取详细的数据类型
* @param x x
*/
export function getType(x: any): string {
const originType = Object.prototype.toString.call(x) // '[object String]'
const spaceIndex = originType.indexOf(' ')
const type = originType.slice(spaceIndex + 1, -1) // 'String'
return type.toLowerCase() // 'string'
}
# 单元测试
import { getType } from "./get-type";
describe("获取详细的数据类型", () => {
it("null", () => {
expect(getType(null)).toBe("null");
});
it("undefined", () => {
expect(getType(undefined)).toBe("undefined");
});
it("number", () => {
expect(getType(100)).toBe("number");
expect(getType(NaN)).toBe("number");
expect(getType(Infinity)).toBe("number");
expect(getType(-Infinity)).toBe("number");
});
it("string", () => {
expect(getType("abc")).toBe("string");
});
it("boolean", () => {
expect(getType(true)).toBe("boolean");
});
it("symbol", () => {
expect(getType(Symbol())).toBe("symbol");
});
it("bigint", () => {
expect(getType(BigInt(100))).toBe("bigint");
});
it("object", () => {
expect(getType({})).toBe("object");
});
it("array", () => {
expect(getType([])).toBe("array");
});
it("function", () => {
expect(getType(() => {})).toBe("function");
expect(getType(class Foo {})).toBe("function");
});
it("map", () => {
expect(getType(new Map())).toBe("map");
});
it("weakmap", () => {
expect(getType(new WeakMap())).toBe("weakmap");
});
it("set", () => {
expect(getType(new Set())).toBe("set");
});
it("weakset", () => {
expect(getType(new WeakSet())).toBe("weakset");
});
it("date", () => {
expect(getType(new Date())).toBe("date");
});
it("regexp", () => {
expect(getType(new RegExp(""))).toBe("regexp");
});
it("error", () => {
expect(getType(new Error())).toBe("error");
});
it("promise", () => {
expect(getType(Promise.resolve())).toBe("promise");
});
});
← Array flatten 手写 new →