在JavaScript中,能够准确地判断一个变量是数组还是对象是非常重要的,因为这决定了我们如何操作这个变量。JavaScript中提供了几种方法来判断它们。
`instanceof` 运算符
`instanceof` 运算符用于检测构造函数的 `prototype` 属性是否出现在对象的原型链中。
let arr = [1, 2, 3];
let obj = { name: 'John' };
console.log(arr instanceof Array); // true
console.log(obj instanceof Array); // false
console.log(arr instanceof Object); // true
console.log(obj instanceof Object); // true
注意:`instanceof` 运算符在多个全局执行上下文(如多个iframe或web worker)中可能不准确。
`Array.isArray()`
这是一个Array的静态方法,用于确定传递的值是否是一个Array。
let arr = [1, 2, 3];
let obj = { name: 'John' };
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false
`Array.isArray()` 是确定一个值是否为数组的最佳方式,因为它可以跨不同的执行上下文工作。
`typeof` 运算符
`typeof` 运算符对数组并不适用。
let arr = [1, 2, 3];
let obj = { name: 'John' };
console.log(typeof arr); // "object"
console.log(typeof obj); // "object"
如你所见,`typeof` 运算符不能准确区分数组和对象。
`Object.prototype.toString.call()`
这是一种跨上下文和框架工作的方法。
let arr = [1, 2, 3];
let obj = { name: 'John' };
console.log(Object.prototype.toString.call(arr)); // "[object Array]"
console.log(Object.prototype.toString.call(obj)); // "[object Object]"
你可以通过以下方式简化这个调用:
let toString = Object.prototype.toString;
let arr = [1, 2, 3];
let obj = { name: 'John' };
console.log(toString.call(arr) === '[object Array]'); // true
console.log(toString.call(obj) === '[object Array]'); // false
自定义 `isOfType` 函数
你也可以创建一个自定义函数,结合以上方法,来返回一个值的类型。
function isOfType(value, type) {
return Object.prototype.toString.call(value) === `[object ${type}]`;
}
let arr = [1, 2, 3];
let obj = { name: 'John' };
console.log(isOfType(arr, 'Array')); // true
console.log(isOfType(obj, 'Array')); // false
console.log(isOfType(obj, 'Object')); // true
这样,你就可以更灵活地检查不同类型。
综上所述,`Array.isArray()` 是最推荐的方式来判断一个值是否为数组,而 `Object.prototype.toString.call()` 是一个更通用的跨上下文解决方案。根据你的具体需求,你可以选择最适合你的方法。