1. 背景
【xe-utils源码 | 01】判断基础类型中,用了 typeof
判断基本类型
【xe-utils源码 | 02】判断Array类型中,用了 Object.prototype.toString.call(obj)
判断如 Array 等更多的类型
但是若遇到了 TypeError
、PlainObject
等类型,用上述方法无法判断出来,如下代码:
console.log(typeof new TypeError()) // Object
console.log(Object.prototype.toString.call(new TypeError())) // [object Error]
遇到这种情况,xe-utils 是如何准确地判断类型?
2. 源码解析
isTypeError.js
源码如下
// isTypeError.js
function isTypeError(obj) {
return obj ? obj.constructor === TypeError : false
}
module.exports = isTypeError
console.log(isTypeError(new Error('error'))) // false
console.log(isTypeError(new TypeError('error'))) // true
isPlainObject.js
源码如下
function isPlainObject(obj) {
return obj ? obj.constructor === Object : false
}
module.exports = isPlainObject
console.log(isPlainObject([])) // false
console.log(isPlainObject({})) // true
从源码中看到,上述两个方法都是通过 constructor
,也就是判断一个实例的构造函数,是否等于父类,来判断其类型。
因此也得到了判断 JavaScript
中实例的方法,但在这里与常用的 instanceof
方法也有差别,需要特别注意:
a instanceof b
:判断的是 a 是否与 b 处于同一条原型链上,若是则返回 truea.constructor === A
:判断的是 a 是否是 A 类的实例对象
两者的差别,代码演示出来就很清晰:
const array = [1, 2, 3]
console.log(array instanceof Array) // true
console.log(array instanceof Object) // true
console.log(array.constructor === Array) // true
console.log(array.constructor === Object) // false
由上可见,使用 constructor
能更加精确地指向对象所对应的类,而对于 instanceof
,只要是处于原型链上的,都会返回 true