JavaScript中如何判断构造函数参数是对象还是数组?
如何区分JavaScript中的普通对象与数组?
场景需求
我需要实现一个Outer类,其构造函数需处理两种参数输入:
- 若传入普通对象(即内部对象的完整结构),直接将其赋值给
this.inner - 若传入数组,则创建默认内部对象,将数组赋值给
value1字段,其余字段按默认规则生成
此前尝试typeof inner === "object"无法区分数组(数组的typeof结果也是"object"),使用inner instanceof Array也未达到预期效果,现寻求准确区分普通对象与数组的方法。
解决方案
方法1:使用Array.isArray()判断数组(推荐)
ES5新增的Array.isArray()是判断数组最可靠的方法,它能准确识别所有数组(包括跨iframe创建的数组),剩下的object类型(排除null)即可判定为普通对象。
示例代码:
class Outer { constructor(inner) { // 先处理null的特殊情况(typeof null === "object") if (inner === null) { throw new Error('参数不能为null'); } if (Array.isArray(inner)) { // 传入的是数组,创建默认内部对象 this.inner = { value1: inner, value2: [], // 此处填入默认值 // 其他默认字段 }; } else if (typeof inner === "object") { // 传入的是普通对象,直接赋值 this.inner = inner; } else { // 处理非对象/数组的参数 throw new Error('参数必须是数组或普通对象'); } } }
方法2:使用Object.prototype.toString.call()做底层判断
这是更通用的类型判断方式,通过调用原生对象的toString方法,返回的字符串能精准标识值的类型:
- 数组返回
"[object Array]" - 普通对象返回
"[object Object]"
示例代码:
class Outer { constructor(inner) { const typeString = Object.prototype.toString.call(inner); if (typeString === "[object Array]") { this.inner = { value1: inner, value2: [], // 默认值 // 其他默认字段 }; } else if (typeString === "[object Object]") { this.inner = inner; } else { throw new Error('参数必须是数组或普通对象'); } } }
为什么instanceof Array可能失效?
instanceof依赖原型链判断,当数组是在另一个iframe中创建时,它的原型指向该iframe的Array.prototype,与当前环境的Array.prototype不是同一个对象,此时inner instanceof Array会返回false,这就是你之前遇到的问题。而Array.isArray()和Object.prototype.toString.call()不受跨环境原型链的影响,判断结果更准确。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

