在JavaScript中,如何检查一个值是否为对象?
如果 typeof yourVariable === 'object'
,那么它就是一个对象或者 null
。
如果你想排除null
、数组或函数,只需这样做:
if (
typeof yourVariable === 'object' &&
!Array.isArray(yourVariable) &&
yourVariable !== null
) {
executeSomeCode();
}
yourVariable !== null
是否更好的做法? - hippietrailtypeof null == 'object'
在 ES6 中不会被修复。他们说:“这个提案已经被拒绝了。它曾在 V8 中实现过,但结果发现它破坏了很多现有的网站。在实现“一个JavaScript”的精神中,这是不可行的。” - Konstantin SmolyaninObject.prototype.toString.call(yourVar)
来检查你需要检查的变量,yourVar 是你需要检查的变量名。对于数组,Object.prototype.toString.call([1,2])
返回 [object Array]
。 - Jose Rui SantosArray.isArray(yourVariable)
。因此,我认为这个回答不应该被downvote。 - Alexander Flenniken更新:
这篇答案不完整且会给出误导性结果。例如,在JavaScript中,null
也被视为 object
类型,更不用说其他一些边缘情况了。请遵循下面的建议,并转到其他“最受欢迎(也是正确的!)答案”:
typeof yourVariable === 'object' && yourVariable !== null
尝试使用typeof(var)
和/或var instanceof something
。编辑:本答案提供了一种检查变量属性的想法,但这并不是检查它是否为对象的万无一失的方法(毕竟根本就没有!)。由于人们倾向于在此处寻找可复制的内容而不进行任何研究,因此我强烈建议他们转向其他最受赞扬(且正确!)的答案。typeof
会返回'object',但对于空值null来说并不是一个对象;而使用Object.create(null)
创建的对象无法使用instanceof
进行判断。 - Nikolaitypeof null
... object
! - Camilo MartinsomeArray instanceof Object //true
或 typeof someArray === 'object' // true
。那么如果你想检测一个数组,可以使用 Object.prototype.toString.call(someObject) === "[object Object]"
或者 "[object Array]"
。 - Con Antonakos让我们在Javascript中定义"对象"。根据MDN文档,每个值都是对象或原始类型:
primitive, primitive value
一个既不是对象也没有任何方法的数据。JavaScript 有 7 种原始数据类型:字符串、数字、大整数、布尔、未定义的值、符号和 null。
什么是原始类型?
3
'abc'
true
null
undefined
什么是对象(即非原始类型)?
Object.prototype
Object.prototype
的对象
Function.prototype
Object
Function
function C(){}
-- 用户定义的函数C.prototype
-- 用户定义函数的原型属性:这不是C
的原型
new C()
-- "new"一个用户定义的函数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文档所述:
对象构造函数为给定的值创建一个对象包装器。如果值为 null 或 undefined,则它将创建并返回一个空对象,否则,它将返回与给定值对应的类型的对象。如果该值已经是一个对象,则它将返回该值。
第三种看起来可行的方法(不确定是否100%有效)是使用Object.getPrototypeOf
,如果其参数不是对象,则会抛出异常:
// 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({})
obj === Object(obj)
返回true
。 - Onur Yıldırım({}).toString.apply(obj) === '[object Object]'
来区分非数组的对象和数组? - MauricioJuanesval instanceof Object
对于数组返回 true。 - Илья Зеленькоunderscore.js 提供了以下方法来判断一个东西是否是真正的对象:
_.isObject = function(obj) {
return obj === Object(obj);
};
更新
由于V8中之前存在的一个bug和微小的性能优化,该方法自underscore.js 1.7.0(2014年8月)以来看起来如下:
_.isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
return obj === Object(obj) && Object.prototype.toString.call(obj) !== '[object Array]'
。 - Daan null
。应该被接受的答案。 - tiffonObject.prototype.toString.call(myVar)
将返回:
"[object Object]"
"[object Array]"
关于此技术的更多信息以及为什么它是typeof的良好替代,请查看这篇文章。
typeof [] === 'object'
--> true
。这就是你需要用到这个方法的原因。 - JondlmObject.prototype.toString.call(3)
-> "[object Number]"
。Object.prototype.toString.call(new Number(3))
-> "[object Number]"
。 - Matt Fenwick如果只是简单地检查 Object
或 Array
,而不需要额外的函数调用(速度),可以使用如下方法。也可以参考这里。
isArray()
isArray = function(a) {
return (!!a) && (a.constructor === Array);
};
console.log(isArray( )); // false
console.log(isArray( null)); // false
console.log(isArray( true)); // false
console.log(isArray( 1)); // false
console.log(isArray( 'str')); // false
console.log(isArray( {})); // false
console.log(isArray(new Date)); // false
console.log(isArray( [])); // true
isLiteralObject()
- 注意:仅适用于Object
字面量,对于自定义对象(例如new Date
或new YourCustomObject
)将返回false
。
isLiteralObject = function(a) {
return (!!a) && (a.constructor === Object);
};
console.log(isLiteralObject( )); // false
console.log(isLiteralObject( null)); // false
console.log(isLiteralObject( true)); // false
console.log(isLiteralObject( 1)); // false
console.log(isLiteralObject( 'str')); // false
console.log(isLiteralObject( [])); // false
console.log(isLiteralObject(new Date)); // false
console.log(isLiteralObject( {})); // true
Array.isArray()
来确定某个东西是否是数组。它通过了你提供的所有测试案例。 - Kip!!a
,isObject(null)
将返回 null
而不是 false
。 - AKG我喜欢简单:
function isObject (item) {
return (typeof item === "object" && !Array.isArray(item) && item !== null);
}
如果该项是JavaScript对象,且不是JavaScript数组,且不是null
...如果这三个条件都为真,则返回true
。如果其中任何一个条件失败,&&
测试将短路并返回false
。如果需要(根据使用null
的方式),可以省略null
测试。new Date()
返回一个对象,而从逻辑上讲,数组不是一个对象,尽管JavaScript处理和报告它们是对象。然而,在实践中,将它们视为相等并没有什么帮助,因为它们并不相同。例如,对象没有length
属性,也没有像push()
这样的方法。有时候你需要给函数多种参数,需要区分数组或对象,特别是如果其他参数依赖于给定的参数类型。 - StanElength
属性或像push
这样的方法,Object.create(Array.prototype)
是一个非数组对象的微不足道的反例,它具有这些属性。数组之所以特殊,是因为它们是具有自定义[[DefineOwnProperty]]本质内部方法的异类对象,但它们仍然是对象。 - Oriollength
属性(我是指对象字面量默认没有 length
属性)。我写的是从 逻辑 角度来说数组不是对象。我在谈论程序逻辑。有时需要检查数组是否是一个“真正”的数组而不是一个“真正”的对象。这就是 Array.isArray()
的作用。想象一下你有一个接受一个对象或对象数组的函数。检查特定属性或方法是一种不好的解决方案。原生方法总是更好的。 - StanEArray.isArray
:function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}
Array.isArray
函数:很惊讶错误答案获得了这么多赞
只有1个回答通过了我的测试!!! 这里我创建了一个简化版:
function isObject(o) {
return o instanceof Object && o.constructor === Object;
}
对我来说,它很清晰简单,而且功能正常!这是我的测试:
console.log(isObject({})); // Will return: true
console.log(isObject([])); // Will return: false
console.log(isObject(null)); // Will return: false
console.log(isObject(/.*/)); // Will return: false
console.log(isObject(function () {})); // Will return: false
再强调一遍:并不是所有的答案都能通过这些测试!!!
如果你需要验证一个对象是否是特定类的实例,你需要检查它的构造函数是否属于你所需的类,比如:
function isDate(o) {
return o instanceof Object && o.constructor === Date;
}
简单测试:
var d = new Date();
console.log(isObject(d)); // Will return: false
console.log(isDate(d)); // Will return: true
因此,您将拥有严格和健壮的代码!
如果您不想创建像isDate
、isError
、isRegExp
等函数,您可以考虑使用这些通用函数:
function isObject(o) {
return o instanceof Object && typeof o.constructor === 'function';
}
对于之前提到的所有测试用例,它可能无法正常工作,但对于所有对象(普通或构造的)来说足够好了。
isObject
在使用 Object.create(null)
时不适用,因为 Object.create
的内部实现如此,这在这里有解释,但你可以在更复杂的实现中使用 isObject
:
function isObject(o, strict = true) {
if (o === null || o === undefined) {
return false;
}
const instanceOfObject = o instanceof Object;
const typeOfObject = typeof o === 'object';
const constructorUndefined = o.constructor === undefined;
const constructorObject = o.constructor === Object;
const typeOfConstructorObject = typeof o.constructor === 'function';
let r;
if (strict === true) {
r = (instanceOfObject || typeOfObject) && (constructorUndefined || constructorObject);
} else {
r = (constructorUndefined || typeOfConstructorObject);
}
return r;
};
已经有一个基于这个实现的npm包v1 在npm上发布了!它适用于所有先前描述的测试案例!
Date
是不恰当的,因为回答确实讨论了 Date
。但是 Date
只是无限可能的类之一,而且这个观点适用于任何其他类。例如:class Foo() {}; var x = new Foo(); isObject(x)
返回 false
。我不知道 OP 的用例是什么,但很容易想象在某些情况下,必须了解 所有可能的类 并针对 每一个特定类 进行检查将是不可行的。 - Yetanotherjoshinstanceof
无法判断从 Object.create(null)
创建的对象。 - CMCDragonkai哦,我的天啊!我认为这可能比以往任何时候都更短,让我们看看:
function isObject(obj)
{
return obj != null && obj.constructor.name === "Object"
}
console.log(isObject({})) // returns true
console.log(isObject([])) // returns false
console.log(isObject(null)) // returns false
typeof JavaScript对象(包括null
)返回"object"
console.log(typeof null, typeof [], typeof {})
检查它们的constructor
属性会返回带有它们名称的函数。
console.log(({}).constructor) // returns a function with name "Object"
console.log(([]).constructor) // returns a function with name "Array"
console.log((null).constructor) //throws an error because null does not actually have a property
Function.name
返回一个函数的只读名称,对于闭包则返回"anonymous"
。
console.log(({}).constructor.name) // returns "Object"
console.log(([]).constructor.name) // returns "Array"
console.log((null).constructor.name) //throws an error because null does not actually have a property
Object.create(null)
,那么为什么你会这样做呢...? - Julian Knightreturn obj != null && obj.constructor && obj.constructor.name === "Object"
。条件'obj.constructor'返回false,因为Object.create(null)创建一个没有属性的对象,甚至没有.__proto__或.constructor。 - jkdevconst isObject = (obj) => (obj ?? false)?.constructor?.name === "Object";
谢谢! - szegheo试试这个
if (objectName instanceof Object) {
alert('An object');
} else {
alert('Not an object');
}
Object.prototype instanceof Object
-> false. Object.create(null) instanceof Object
-> false. - Matt Fenwicknew Date() instanceof Object
=> true - mauron85Date
е’Ңж•°з»„йғҪжҳҜеҜ№иұЎгҖӮ - InSync
null
是否是对象)。 - user395760