如何检查值是否是JavaScript中的对象?
当前回答
检查值类型的最合理方法似乎是typeof运算符。唯一的问题是它已经严重损坏:
它为null返回“object”,这属于null类型。它为属于Object类型的可调用对象返回“函数”。对于非标准的不可调用对象,它可以返回(几乎)它想要的任何内容。例如,IE似乎喜欢“未知”。唯一被禁止的结果是“函数”和原始类型。
typeof仅对非空基元可靠。因此,检查值是否为对象的一种方法是确保typeof返回的字符串与原语不对应,并且对象不为空。然而,问题是未来的标准可能会引入一种新的原始类型,我们的代码会将其视为一个对象。新类型并不经常出现,但例如ECMAScript 6引入了Symbol类型。
因此,我只推荐结果随值是否为对象而变化的方法,而不是typeof。以下是
测试值是否属于Object类型的正确方法的全面但不详尽的列表。
对象构造函数Object构造函数将传递的参数强制为对象。如果它已经是一个对象,则返回相同的对象。因此,您可以使用它将值强制转换为对象,并将该对象与原始值严格比较。以下函数需要ECMAScript 3,它引入了==:函数isObject(value){/*需要ECMAScript 3或更高版本*/return Object(value)==value;}我喜欢这种方法,因为它简单且自我描述,类似的检查也适用于布尔值、数字和字符串。但是,请注意,它依赖于全局对象,而不是隐藏或更改。施工人员实例化构造函数时,它可以返回一个不同于刚刚创建的实例的值。但该值将被忽略,除非它是一个对象。以下函数需要ECMAScript 3,它允许构造函数返回非对象。在抛出错误的ECMAScript 3之前,try语句当时不存在。函数isObject(value){/*需要ECMAScript 3或更高版本*/return new函数(){return value;}()==value;}虽然比上一个例子简单一点,但这个例子不依赖任何全局属性,因此可能是最安全的。此值旧的ECMAScript规范要求此值为对象。ECMAScript 3引入了Function.prototype.call,它允许调用具有任意此值的函数,但强制为对象。ECMAScript 5引入了一个严格模式,删除了这种行为,但在草率模式下,我们仍然可以(但可以说不应该)依赖它。函数isObject(value){/*需要ECMAScript 3或更高版本处于草率模式*/return函数(){return this==value;}.call(value);}[[原型]]所有普通对象都有一个名为[[Prototype]]的内部槽,其值决定它从哪个其他对象继承。该值只能是对象或null。因此,您可以尝试创建继承自所需值的对象,并检查其是否有效。Object.create和Object.getPrototypeOf都需要ECMAScript 5。函数isObject(value){/*需要ECMAScript 5或更高版本*/尝试{对象.create(value);返回值!==无效的}捕获(错误){return false;}}函数isObject(value){/*需要ECMAScript 5或更高版本*/函数构造函数(){}Constructor.prototype=值;return Object.getPrototypeOf(new Constructor())==值;}一些新的ECMAScript 6方式ECMAScript 6引入了一些新的间接方法来检查值是否为对象。他们使用前面看到的方法将值传递给一些需要对象的代码,该对象封装在try语句中以捕获错误。一些隐藏的例子,不值得评论函数isObject(value){/*需要ECMAScript 6或更高版本*/尝试{Object.setPrototypeOf({},值);返回值!==无效的}捕获(错误){return false;}}函数isObject(value){/*需要ECMAScript 6或更高版本*/尝试{新的WeakSet([value]);返回true;}捕获(错误){return false;}}
注意:我有意跳过了一些方法,例如Object.getPrototypeOf(value)(ES5)和Reflect方法(ES6),因为它们调用了可能会做坏事的基本内部方法,例如,如果value是代理。出于安全原因,我的示例仅引用值,而不直接访问它。
其他回答
更新:
这个答案是不完整的,给出了误导性的结果。例如,null也被认为是JavaScript中的对象类型,更不用说其他几种边缘情况。遵循下面的建议,然后转到其他“最支持(和正确!)的答案”:
typeof yourVariable === 'object' && yourVariable !== null
原答覆:
尝试使用typeof(var)和/或var instanceof。
编辑:这个答案给出了如何检查变量财产的思路,但它并不是检查它是否是一个对象的万无一失的方法(毕竟根本没有方法。
我有一段代码片段可以使用。当没有给出整段代码时,我觉得很困惑,所以我自己创建了它:
<!DOCTYPE html>
<html>
<body>
<button onclick="myFunc()">Try it</button>
<script>
var abc = new Number();
// var abc = 4;
//this is a code variation which will give a diff alert
function myFunc()
{
if(abc && typeof abc === "object")
alert('abc is an object and does not return null value');
else
alert('abc is not an object');
}
</script>
</body>
</html>
这是一个老问题,但我想把它留在这里。大多数人都在检查变量是否为{},这意味着一个键值配对,而不是JavaScript用于给定对象的下划线构造,因为老实说,JavaScript中的大部分内容都是一个对象。所以把它从路上拿开。如果你这样做。。。
let x = function() {}
typeof x === 'function' //true
x === Object(x) // true
x = []
x === Object(x) // true
// also
x = null
typeof null // 'object'
大多数时候,我们想要的是知道我们是否有来自API的资源对象或从ORM返回的数据库调用。然后,我们可以测试是否不是数组、是否为null、是否为“function”类型、是否为Object
// To account also for new Date() as @toddmo pointed out
x instanceof Object && x.constructor === Object
x = 'test' // false
x = 3 // false
x = 45.6 // false
x = undefiend // false
x = 'undefiend' // false
x = null // false
x = function(){} // false
x = [1, 2] // false
x = new Date() // false
x = {} // true
检查值类型的最合理方法似乎是typeof运算符。唯一的问题是它已经严重损坏:
它为null返回“object”,这属于null类型。它为属于Object类型的可调用对象返回“函数”。对于非标准的不可调用对象,它可以返回(几乎)它想要的任何内容。例如,IE似乎喜欢“未知”。唯一被禁止的结果是“函数”和原始类型。
typeof仅对非空基元可靠。因此,检查值是否为对象的一种方法是确保typeof返回的字符串与原语不对应,并且对象不为空。然而,问题是未来的标准可能会引入一种新的原始类型,我们的代码会将其视为一个对象。新类型并不经常出现,但例如ECMAScript 6引入了Symbol类型。
因此,我只推荐结果随值是否为对象而变化的方法,而不是typeof。以下是
测试值是否属于Object类型的正确方法的全面但不详尽的列表。
对象构造函数Object构造函数将传递的参数强制为对象。如果它已经是一个对象,则返回相同的对象。因此,您可以使用它将值强制转换为对象,并将该对象与原始值严格比较。以下函数需要ECMAScript 3,它引入了==:函数isObject(value){/*需要ECMAScript 3或更高版本*/return Object(value)==value;}我喜欢这种方法,因为它简单且自我描述,类似的检查也适用于布尔值、数字和字符串。但是,请注意,它依赖于全局对象,而不是隐藏或更改。施工人员实例化构造函数时,它可以返回一个不同于刚刚创建的实例的值。但该值将被忽略,除非它是一个对象。以下函数需要ECMAScript 3,它允许构造函数返回非对象。在抛出错误的ECMAScript 3之前,try语句当时不存在。函数isObject(value){/*需要ECMAScript 3或更高版本*/return new函数(){return value;}()==value;}虽然比上一个例子简单一点,但这个例子不依赖任何全局属性,因此可能是最安全的。此值旧的ECMAScript规范要求此值为对象。ECMAScript 3引入了Function.prototype.call,它允许调用具有任意此值的函数,但强制为对象。ECMAScript 5引入了一个严格模式,删除了这种行为,但在草率模式下,我们仍然可以(但可以说不应该)依赖它。函数isObject(value){/*需要ECMAScript 3或更高版本处于草率模式*/return函数(){return this==value;}.call(value);}[[原型]]所有普通对象都有一个名为[[Prototype]]的内部槽,其值决定它从哪个其他对象继承。该值只能是对象或null。因此,您可以尝试创建继承自所需值的对象,并检查其是否有效。Object.create和Object.getPrototypeOf都需要ECMAScript 5。函数isObject(value){/*需要ECMAScript 5或更高版本*/尝试{对象.create(value);返回值!==无效的}捕获(错误){return false;}}函数isObject(value){/*需要ECMAScript 5或更高版本*/函数构造函数(){}Constructor.prototype=值;return Object.getPrototypeOf(new Constructor())==值;}一些新的ECMAScript 6方式ECMAScript 6引入了一些新的间接方法来检查值是否为对象。他们使用前面看到的方法将值传递给一些需要对象的代码,该对象封装在try语句中以捕获错误。一些隐藏的例子,不值得评论函数isObject(value){/*需要ECMAScript 6或更高版本*/尝试{Object.setPrototypeOf({},值);返回值!==无效的}捕获(错误){return false;}}函数isObject(value){/*需要ECMAScript 6或更高版本*/尝试{新的WeakSet([value]);返回true;}捕获(错误){return false;}}
注意:我有意跳过了一些方法,例如Object.getPrototypeOf(value)(ES5)和Reflect方法(ES6),因为它们调用了可能会做坏事的基本内部方法,例如,如果value是代理。出于安全原因,我的示例仅引用值,而不直接访问它。
如果typeof yourVariable==“object”,则它是一个对象或null。
如果要排除null、数组或函数,只需执行以下操作:
if (
typeof yourVariable === 'object' &&
!Array.isArray(yourVariable) &&
yourVariable !== null
) {
executeSomeCode();
}
推荐文章
- 将.NET DateTime转换为JSON
- SameSite警告Chrome 77
- 在ES6 (ECMAScript 6)中是否有一种不带可变变量的循环x次的机制?
- 克隆对象没有引用javascript
- 验证字符串是否为正整数
- 如何获得一个键/值JavaScript对象的键
- 什么时候JavaScript是同步的?
- 如何在Typescript中解析JSON字符串
- Javascript reduce()在对象
- 在angularJS中& vs @和=的区别是什么
- 错误"Uncaught SyntaxError:意外的标记与JSON.parse"
- JavaScript中的querySelector和querySelectorAll vs getElementsByClassName和getElementById
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别