typeof bar=="object"判断类型为对象的潜在陷阱及如何避免

33 阅读2分钟

typeof bar=="object"判断类型为对象的潜在陷阱及如何避免

在 JavaScript 中,使用 typeof bar == "object" 判断一个变量是否为对象时,存在一些潜在陷阱。以下是常见问题及解决方法:

1. null 也被判断为对象

typeof null 返回 "object",这是 JavaScript 的历史遗留问题。

示例:

const bar = null;
console.log(typeof bar === "object"); // true

解决方法:

额外检查 bar !== null

if (bar !== null && typeof bar === "object") {
    console.log("bar 是对象");
}

2. 数组也被判断为对象

typeof [] 返回 "object",因为数组是特殊的对象。

示例:

const bar = [1, 2, 3];
console.log(typeof bar === "object"); // true

解决方法:

使用 Array.isArray() 排除数组。

if (typeof bar === "object" && bar !== null && !Array.isArray(bar)) {
    console.log("bar 是对象");
}

3. 函数也被判断为对象

typeof function() {} 返回 "function",但函数也是对象。

示例:

const bar = function() {};
console.log(typeof bar === "object"); // false

解决方法:

通常不需要特别处理,因为 typeof 已经将函数单独分类。

4. 包装对象(如 new String()

通过构造函数创建的包装对象(如 new String("hello"))也是对象。

示例:

const bar = new String("hello");
console.log(typeof bar === "object"); // true

解决方法:

使用 Object.prototype.toString 判断具体类型。

if (Object.prototype.toString.call(bar) === "[object Object]") {
    console.log("bar 是普通对象");
}

5. 使用 Object.prototype.toString 判断类型

Object.prototype.toString 可以更精确地判断对象类型。

示例:

const bar = {};
console.log(Object.prototype.toString.call(bar)); // [object Object]

完整判断:

function isPlainObject(obj) {
    return Object.prototype.toString.call(obj) === "[object Object]";
}

console.log(isPlainObject({})); // true
console.log(isPlainObject([])); // false
console.log(isPlainObject(null)); // false
console.log(isPlainObject(new String("hello"))); // false

6. 使用 instanceof 判断对象

instanceof 可以判断对象是否属于某个构造函数。

示例:

const bar = {};
console.log(bar instanceof Object); // true

注意:

  • instanceof 会检查原型链,可能不适用于跨框架对象。
  • null 和原始类型(如 "hello")会返回 false

7. 使用 constructor 判断对象

通过 constructor 属性可以判断对象的构造函数。

示例:

const bar = {};
console.log(bar.constructor === Object); // true

注意:

  • constructor 属性可能被修改。
  • nullundefined 没有 constructor 属性。

总结

方法优点缺点
typeof bar === "object"简单直接无法区分null、数组等
Object.prototype.toString精确判断对象类型代码较长
instanceof检查原型链不适用于跨框架对象
constructor直接判断构造函数可能被修改

推荐方法:

function isPlainObject(obj) {
    return obj !== null && typeof obj === "object" && !Array.isArray(obj);
}

// 或
function isPlainObject(obj) {
    return Object.prototype.toString.call(obj) === "[object Object]";
}

通过合理选择判断方法,可以避免 typeof bar == "object" 的潜在陷阱,准确判断对象类型。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github