检查是否为对象

5
我需要检查一个变量是否是纯对象实例。例如:HTMLElement是Object的实例。但我真正需要检查的是它是否仅仅是一个对象,比如{a: true, b: false}。它不能验证一个数组。
注意:如果更好,我可以使用Chrome的新功能。

为什么你需要这样做? - hugomg
你真的想要查看一个对象是否是宿主或本地对象吗?HTMLElement不一定是内置Object对象的实例。元素是宿主对象,因此不需要遵循任何特定的继承模式(某些浏览器不实现任何模式,也不将其实现为Object的实例)。 - RobG
1
查看 jQuery 的源代码 http://code.jquery.com/jquery-1.9.1.js 中的 http://api.jquery.com/jQuery.isPlainObject/,然后关闭这个问题,直到你变得盲目。 - Andy Ray
1
如果代码只需要在一组非常有限的浏览器中运行,可以检查 object.__proto__ === Object.prototype。但绝对不建议在普通网页中这么做。 - RobG
1
@AndyRay - jQuery的方法相当糟糕,其中包含这个宝石:Own properties are enumerated firstly,它不仅没有任何相关标准的依据,而且在实践中被证明是错误的。它之所以不会导致错误的唯一原因可能是以下行很少被执行(或者根本不会被执行)。 - RobG
2个回答

8

感谢所有的回复...但这对我来说是完美和快速的。谢谢你! - David Rodrigues
构造函数属性可以被设置,因此很容易被欺骗:var a = []; a.constructor = Object; o.constructor === Object; // true - RobG
1
@RobG 当然,你可以用JS做很多让自己搬起石头砸自己脚的事情。你也可以伪造object.__proto__,但我想这样会使某些东西成为一个对象吧? - Ruan Mendes
@RobG:可能更好的例子是常见的替换自定义构造函数的原型对象,例如:MyCtor.prototype = {myMethod: function() {}, ...} - the system
@JuanMendes——只是指出这一点,让问题提出者(以及其他人)做出明智的决定。JavaScript的松散类型是其他语言使用者难以接受的事情之一。“对象何时成为对象”是一个谜团,最好避免,因为没有简单的答案。 - RobG

2
var proto = Object.getPrototypeOf(obj);

var protoproto = Object.getPrototypeOf(proto);

if (proto === Object.prototype && protoproto === null) {
    //plain object
}

如果你将创建原型为 null 的对象,可以去掉 protoproto,只需将 protoObject.prototypenull 进行比较。但这样做的危险在于它不防止被传递给本身的 Object.prototype,可能会意外扩展 Object.prototype
可以使用以下更简短和更安全的方法:
var proto = Object.getPrototypeOf(obj);

if (proto && Object.getPrototypeOf(proto) === null) {
    // plain object
}


附注:最低浏览器版本要求:Firefox 3.5,Chrome 5,IE 9。请参阅:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf - Raptor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接