检查一个值是否是 JavaScript 中的对象

IT技术 javascript types javascript-objects
2021-01-16 17:06:04

你如何检查一个值是否是 JavaScript 中的对象?

6个回答

如果typeof yourVariable === 'object',它是一个对象或null

如果您想null排除数组或函数,只需执行以下操作:

if (
    typeof yourVariable === 'object' &&
    !Array.isArray(yourVariable) &&
    yourVariable !== null
) {
    executeSomeCode();
}

@Tresdin 最好的方法是运行Object.prototype.toString.call(yourVar),作为你需要检查的变量在数组的情况下,Object.prototype.toString.call([1,2])返回[object Array]
2021-03-21 17:06:04
@RightSaidFred 似乎typeof null == 'object'不会在ES6 中修复他们说:This proposal has been rejected. It was implemented in V8 but it turned out that it broke a lot of existing sites. In the spirit of One JavaScript this is not feasible.
2021-04-05 17:06:04
在这种情况下会yourVariable !== null是更好的做法吗?
2021-04-06 17:06:04
因为数组也被认为是一个对象,所以你还应该检查Array.isArray(yourVariable).
2021-04-06 17:06:04
函数也是对象,应该包含在您的检查中。
2021-04-08 17:06:04

更新

这个答案是不完整的,并给出了误导性的结果例如,在 JavaScript 中null也被认为是类型object,更不用说其他几个边缘情况了。遵循下面的建议并转到其他“最受好评(和正确!)答案”

typeof yourVariable === 'object' && yourVariable !== null

原答案

尝试使用typeof(var)和/或var instanceof something.

编辑:这个答案给出了如何检查变量属性的想法,但它不是一个防弹配方(毕竟根本没有配方!)来检查它是否是一个远离它的对象。由于人们倾向于在不做任何研究的情况下从这里寻找可以复制的东西,我强烈建议他们转向另一个最受好评(并且正确!)的答案。

@Jonathan,有更好的理由不赞成我的回答,你有军事背景吗?:)
2021-03-12 17:06:04
这不应该是公认的答案。除了乔纳森提出的文体问题之外,它完全不正确并且没有提出@matt-fenwick 的回答中非常重要的微妙之处。
2021-03-14 17:06:04
数组也将作为“对象”返回,如:someArray instanceof Object //truetypeof someArray === 'object' // true怎么样:Object.prototype.toString.call(someObject) === "[object Object]",或者"[object Array]"如果你想检测一个数组?
2021-03-16 17:06:04
typeof null…… object
2021-03-18 17:06:04
这个答案是不正确的。typeof为 null 返回 'object',它不是一个对象,并且instanceof不适用于使用Object.create(null).
2021-04-01 17:06:04

让我们在 Javascript 中定义“对象”根据MDN 文档,每个值要么是对象,要么是原语:

原始值,原始值

不是对象且没有任何方法的数据。JavaScript 有 7 种原始数据类型:string、number、bigint、boolean、undefined、symbol 和 null。

什么是原始人?

  • 3
  • 'abc'
  • true
  • null
  • undefined

什么是对象(即不是原始对象)?

  • Object.prototype
  • 一切都源于 Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} -- 用户自定义函数
    • C.prototype-- 用户定义函数的原型属性:这不是 C原型
      • new C() -- "new"-ing 一个用户定义的函数
    • Math
    • Array.prototype
      • 数组
    • {"a": 1, "b": 2} -- 使用文字符号创建的对象
    • new Number(3) -- 原语的包装器
    • ......许多其他事情......
  • Object.create(null)
  • 一切都源于 Object.create(null)

如何检查一个值是否是一个对象

instanceof 本身不起作用,因为它错过了两种情况:

// oops:  isObject(Object.prototype) -> false
// oops:  isObject(Object.create(null)) -> false
function isObject(val) {
    return val instanceof Object; 
}

typeof x === 'object'不会工作,因为误报 ( null) 和漏报(函数):

// oops: isObject(Object) -> false
function isObject(val) {
    return (typeof val === 'object');
}

Object.prototype.toString.call 不会工作,因为所有原语的误报:

> Object.prototype.toString.call(3)
"[object Number]"

> Object.prototype.toString.call(new Number(3))
"[object Number]"

所以我使用:

function isObject(val) {
    if (val === null) { return false;}
    return ( (typeof val === 'function') || (typeof val === 'object') );
}

@Daan 的回答似乎也有效:

function isObject(obj) {
  return obj === Object(obj);
}

因为,根据MDN 文档

Object 构造函数为给定的值创建一个对象包装器。如果值为 null 或 undefined,它将创建并返回一个空对象,否则,它将返回一个与给定值对应的类型的对象。如果该值已经是一个对象,它将返回该值。


第三种似乎有效的方法(不确定是否为 100%)是使用Object.getPrototypeOfwhich如果其参数不是对象则抛出异常

// these 5 examples throw exceptions
Object.getPrototypeOf(null)
Object.getPrototypeOf(undefined)
Object.getPrototypeOf(3)
Object.getPrototypeOf('abc')
Object.getPrototypeOf(true)

// these 5 examples don't throw exceptions
Object.getPrototypeOf(Object)
Object.getPrototypeOf(Object.prototype)
Object.getPrototypeOf(Object.create(null))
Object.getPrototypeOf([])
Object.getPrototypeOf({})
为什么不({}).toString.apply(obj) === '[object Object]'区分数组和不是数组的对象
2021-03-11 17:06:04
getPrototypeOf 不适用于例如已撤销的代理,这些代理是对象但会抛出。
2021-03-15 17:06:04
obj === Object(obj)返回true数组。
2021-04-01 17:06:04
正如我在回答中提到的,@Illuminator 数组Javascript中的对象。
2021-04-07 17:06:04
var x = []; console.log(x === Object(x)); // return true
2021-04-09 17:06:04

underscore.js提供了以下方法来确定某物是否真的是一个对象:

_.isObject = function(obj) {
  return obj === Object(obj);
};

更新

由于先前 V8 中的错误和微小的微速度优化,自underscore.js 1.7.0(2014 年 8 月)以来,该方法如下所示

_.isObject = function(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};
因为大多数情况下,您希望将 {} 与 [] 区分开来,例如作为函数中的输入
2021-03-15 17:06:04
很好的答案。手柄null也一样。应该是公认的答案。
2021-03-15 17:06:04
在 javascript 中,数组也是一个对象,所以大多数时候你想排除数组: return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
2021-03-20 17:06:04
为什么要排除数组?它们是成熟的对象。
2021-03-24 17:06:04
@Nickolai .. 并用于迭代嵌套对象。
2021-03-27 17:06:04

Object.prototype.toString.call(myVar) 将返回:

  • "[object Object]" 如果 myVar 是一个对象
  • "[object Array]" 如果 myVar 是一个数组
  • 等等。

有关这方面的更多信息以及为什么它是 typeof 的一个很好的替代品,请查看这篇文章

getType=function(obj){return Object.prototype.toString.call(obj).match(/\[object (\w+)\]/)[1];};
2021-03-13 17:06:04
@Christophe 你为什么这么认为?恕我直言,在 OP 没有为“对象”给出任何其他定义的情况下,我认为使用在整个 ECS 规范中一致使用的定义似乎是最合理的。
2021-03-31 17:06:04
@Christophe 不区分原语和对象Object.prototype.toString.call(3)-> "[object Number]". Object.prototype.toString.call(new Number(3))-> "[object Number]"
2021-04-02 17:06:04
我最近了解到typeof [] === 'object'--> true. 这就是你需要这个方法。
2021-04-06 17:06:04
@MattFenwick 我不认为这是 OP 试图识别的那种“对象”
2021-04-06 17:06:04