Skip to main content

判断是否是数组-判断对象-空对象

在 JavaScript 中所有数据类型严格意义上都是对象,但实际使用中我们还是有类型之分,如果要判断一个变量是数组还是对象使用 typeof 搞不定,因为它全都返回 object

判断数组

Array.isArray,根据 Object 的原型对象判断

let testArr = [1, 2, 3]
// let testArr = {}
console.log(Array.isArray(testArr));//true

Object.prototype.toString().call()可以获取到对象的不同类型

根据 Object 的原型对象判断: Object 的原型对象上有一个 toString 方法,toString 方法默认被所有对象继承,返回 "[object type]" 字符串。但此方法经常被原型链上的同名方法覆盖,需要通过 Object.prototype.toString.call() 强行调用。

let testArr = [1, 2, 3]
console.log('is arr2:', Object.prototype.toString.call(testArr) === '[object Array]')

console.log('test:', Object.prototype.toString.call([]) === '[object Array]') // true

instanceof检测prototype,不可靠

运算符用于检验构造函数的prototype属性是否出现在对象的原型链中的任何位置,返回一个布尔值 需要注意的是,prototype属性是可以修改的,所以并不是最初判断为true就一定永远为真。

let testArr = [1, 2, 3]

console.log('is arr3:', testArr instanceof Array) // true
console.log('is arr3:', testArr instanceof Object) // true

arrA.constructor->不可靠

缺点: 如果 arr 的 constructor 被修改,则无法做出正确判断。

const arrA = [1, 2, 3, 4]

// 方法4:对象的 constructor 属性
console.log(arrA.constructor === Array) // true

判断对象

之所以使用Object.prototype.toString,而不是obj.toString是因为有些对象的原型可能重写了toString方法

call()具有时效性,不会副作用影响

const obj = {}
const arr = []

// 方法1:toString(推荐)
console.log('1:', Object.prototype.toString.call(obj) === '[object Object]')
console.log('2:', Object.prototype.toString.call([]) === '[object Array]') // true

// 方式2.instanceof 注意的是由于数组也是对象,因此用 arr instanceof Object 也为true。
console.log('3:', obj instanceof Object)
console.log('4.arr instanceof Object:', arr instanceof Object) // true

// 方法3: 多重判断,缺点:太繁琐
let result = { a: '22' }
let result2 = []
console.log('是否对象1:', typeof result === 'object' && result !== null) // true
console.log('是否对象2-过滤不了数组:', typeof result2 === 'object' && result !== null) // true
console.log('数组是否对象3:', typeof result === 'object' && result instanceof Array && result !== null) // false
let target = result
console.log('{}是否对象4:', typeof target === 'object' && target instanceof Array && target !== null) // true

判断是否空对象

// 方法1: Object.getOwnPropertyNames()方法
// 返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组
console.log('2-getOwnPropertyNames返回对象的自有属性:', Object.getOwnPropertyNames(object2).length === 0);

//方法2: Object.keys
// 缺点:如同使用for in循环进行判断一样,Object.keys方法也只返回可枚举属性,所以并不是很完美。
let obj2 = { a: 12 }
console.log('是否空对象:', Object.keys(obj2).length === 0)

// 方法3:不常用stringify
let objA = {}
console.log('是否空对象:', JSON.stringify(objA) === '{}')