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


当前回答

lodash有isPlainObject,这可能是许多来到这个页面的人都在寻找的。当给定函数或数组时,它返回false。

其他回答

您可以使用JSON.stringify来测试Object,如下所示:

var测试={}if(JSON.stringify(测试)[0]==“{”){console.log('这是一个对象')}

我认为有这么多答案的原因是,无论你是否喜欢,很多东西都是javascript中的对象。

您可以像任何其他对象一样迭代数组的“键”。。。

var key, 
    arr = ['one', 'two', 'three'];
for (key in arr)
    console.log(`${key}=${arr[key]}`);

console.log(arr[1]);
console.log(arr['1']);

// 0=one
// 1=two
// 2=three
// two
// two

数组是特殊的(像许多对象一样),因为它有一些通用对象没有的财产/方法(例如长度、forEach等)。

所以这个问题应该是:如何过滤特定类型的对象?

毕竟,我可以很容易地实现自己的数组、正则表达式或符号,它也可以是一个对象,但可能会通过各种“它是真实对象吗?”测试。。。。因为它是一个真实的物体。

所以你想过滤到某些类型的javascript对象。。。

最好的方法是只做特性测试。例如,您是否关心它是否具有长度属性?示例:浏览器中的NodeList看起来像一个数组,可以像数组一样迭代,但不是数组。

无论如何,如果您只想过滤掉特定类型的对象,那么只有您才能定义要过滤的对象。是否要筛选出RegExp?日期大堆浏览器DOM对象?只有你才能决定你的过滤链是什么样子。您可以使用直通开关来构建紧凑的过滤器。


function typeOfIs(val, type) {
    return typeof val == type;
}

function constructorIs(val, constructor) {
    return val && constructor && val.constructor === constructor;
}

function isObject(val) {
    // catch the easy non-object values
    if (!typeOfIs(val, 'object')) 
        return false;

    // catch the cases you don't want to consider to be 
    // "real" objects for your use-case
    switch (true) {
        case val === null:
        case Array.isArray(val):
        case typeOfIs(val, 'function'):
        case constructorIs(val, RegExp):
            return false;
        default:
            return true;
    }
}
function test(val) {
    console.log(Object.prototype.toString.call(val)+': '+isObject(val));
}
test(undefined);
test(null);
test(function () {});
test(Symbol('foo'));
test(1);
test(true);
test(false);
test('hello world');
test([]);
test(/.*/g);
test(new Date()); // true (because we didn't filter for it)
test({});  // true

特性测试

但更好的方法可能是询问为什么要筛选,或者只测试给定变量上是否存在您需要/期望的财产/函数。。。如果它们存在,使用变量,不要担心它是某种类型的对象还是另一种类型的对象。如果它们不存在,则抛出一个API错误,即您被传递了一些类型不正确的值(即缺少预期的财产/函数)。

e.g.

if (typeof someVariable.hasOwnProperty == 'function')
    // ...

一个基于Matt Fenwick对其完整答案的第三个选项的NodeJS控制台实验。只要稍微调整一下就能判断真假。

以下对象测试返回false。

> if(Object.getPrototypeOf('v') === Object.prototype){console.log(true);}else{console.log(false);}
false
undefined
> if(Object.getPrototypeOf(1) === Object.prototype){console.log(true);}else{console.log(false);}
false
undefined
> if(Object.getPrototypeOf(false) === Object.prototype){console.log(true);}else{console.log(false);}
false
undefined
> if(Object.getPrototypeOf(['apple']) === Object.prototype){console.log(true);}else{console.log(false);}
false
undefined

对象将返回true。

> if(Object.getPrototypeOf({'this':10}) === Object.prototype){console.log(true);}else{console.log(false);}
true
undefined

简单的工作解决方案:

function isObject(value) {
    return !(value instanceof Date) && !Array.isArray(value) && !Object.is(value, null) && !Object.is(value, undefined) && !(value instanceof Function)
}
const isObject = function(obj) {
  const type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

!!obj是检查obj是否正确(以过滤空值)的简写