如何检查值是否是JavaScript中的对象?
当前回答
我喜欢用这个
function isObject (obj) {
return typeof(obj) == "object"
&& !Array.isArray(obj)
&& obj != null
&& obj != ""
&& !(obj instanceof String) }
我认为在大多数情况下,Date必须作为Object通过检查,因此我不会过滤掉日期
其他回答
lodash有isPlainObject,这可能是许多来到这个页面的人都在寻找的。当给定函数或数组时,它返回false。
您可以使用JSON.stringify来测试Object,如下所示:
var测试={}if(JSON.stringify(测试)[0]==“{”){console.log('这是一个对象')}
在阅读并尝试了许多实现之后,我注意到很少有人尝试检查JSON、Math、文档或原型链长度超过1步的对象等值。
我认为,与其检查变量的类型,然后删除边缘事例,不如尽可能简单地进行检查,以避免在添加了注册为“对象”类型的新原语或本地对象时进行重构。
毕竟,typeof运算符会告诉您某个对象是否是JavaScript的对象,但JavaScript对对象的定义对于大多数真实场景来说太宽泛了(例如typeof null==“object”)。下面是一个函数,它通过基本上重复两次检查来确定变量v是否为对象:
只要v的字符串化版本为“[object object]”,就会启动一个循环。我希望函数的结果与下面的日志完全相同,所以这是我最终得出的唯一“对象性”标准。如果失败,函数将立即返回false。v被链中的下一个原型替换为v=Object.getPrototypeOf(v),但也在之后直接求值。当v的新值为null时,这意味着包括根原型(很可能是链中唯一的原型)在内的每个原型都通过了while循环中的检查,我们可以返回true。否则,新的迭代开始。
函数isObj(v){while(Object.product.toString.call(v)=='[Object Object]')if((v=Object.getPrototypeOf(v))==null)返回truereturn false}console.log('FALSE:')console.log('[]->',isObj([]))console.log('ull->',isObj(null))console.log('文档->',isObj(文档))console.log('JSON->',isObj(JSON))console.log('function->',isObj(函数(){}))console.log('newDate()->',isObj(newDate(()))console.log('RegExp->',isObj(/./))console.log('TRUE:')console.log(“{}->”,isObj({}))console.log('newObject()->',isObj(newObject(()))console.log('新对象(null)->',isObj(新对象(空)))console.log('newObject({})->',isObj(newObject({foo:'bar'})))console.log('Object.prototype->',isObj(Object.prototype))console.log('Object.create(null)->',isObj(Object.create(null)))console.log(“Object.create({})->”,isObj(Object.create({foo:'bar'})))console.log(“deep继承->”,isObj(Object.create(Object.create({foo:'bar'}))))
var isArray=function(value){
if(Array.isArray){
return Array.isArray(value);
}else{
return Object.prototype.toString.call(value)==='[object Array]';
}
}
var isObject=function(value){
return value !== null&&!isArray(value) && typeof value === 'object';
}
var _val=new Date;
console.log(isObject(_val));//true
console.log(Object.prototype.toString.call(_val)==='[object Object]');//false
由于对于如何正确处理这个问题似乎有很多困惑,我将留下我的2美分(这个答案符合规范,在任何情况下都会产生正确的结果):
测试原语:未定义的空布尔字符串数
function isPrimitive(o){return typeof o!=='object'||null}
对象不是基本体:
function isObject(o){return !isPrimitive(o)}
或者:
function isObject(o){return o instanceof Object}
function isPrimitive(o){return !isObject(o)}
测试任何阵列:
const isArray=(function(){
const arrayTypes=Object.create(null);
arrayTypes['Array']=true;
arrayTypes['Int8Array']=true;
arrayTypes['Uint8Array']=true;
arrayTypes['Uint8ClampedArray']=true;
arrayTypes['Int16Array']=true;
arrayTypes['Uint16Array']=true;
arrayTypes['Int32Array']=true;
arrayTypes['Uint32Array']=true;
arrayTypes['BigInt64Array']=true;
arrayTypes['BigUint64Array']=true;
arrayTypes['Float32Array']=true;
arrayTypes['Float64Array']=true;
return function(o){
if (!o) return false;
return !isPrimitive(o)&&!!arrayTypes[o.constructor.name];
}
}());
测试对象排除:日期RegExp布尔数字字符串函数任意数组
const isObjectStrict=(function(){
const nativeTypes=Object.create(null);
nativeTypes['Date']=true;
nativeTypes['RegExp']=true;
nativeTypes['Boolean']=true;
nativeTypes['Number']=true;
nativeTypes['String']=true;
nativeTypes['Function']=true;
return function(o){
if (!o) return false;
return !isPrimitive(o)&&!isArray(o)&&!nativeTypes[o.constructor.name];
}
}());