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


当前回答

通过逆向选择的不同方法:

我回顾了这里的所有答案,但仍然缺少一种不同的方法。根据MDN文档,JavaScript中的对象是非原始值。基本值:

布尔型Null类型未定义的类型数字类型BigInt类型字符串类型符号类型

基于这一事实,以下方法正在实施逆向选择:

//根据MDN文档检查值是否为原始值:函数为PrimitiveValue(value){返回(值类型==“符号”||类型值==“字符串”||值类型==“数字”||类型值==“boolean”||类型值==“未定义”||值==空||类型值==“bigint”);};//检查输入是否不是原始值,因此对象:函数isObject(输入){if(isPrimitiveValue(输入)){return false;}返回true;};console.log(isObject(10));//假的console.log(isObject(〔{foo:“bar”}〕));//真的console.log(isObject({a:1,b:2,c:3}));//真的console.log(isObject(Object.getPrototypeOf(“foo”));//真的console.log(isObject(符号(“foo”));//假的console.log(isObject(BigInt(9007199254740991));//假的console.log(isObject(null));//假的console.log(isObject(未定义));//假的console.log(isObject(false));//假的console.log(isObject({}));//真的

其他回答

我们可以只用一行来检查,这里obj可以是任何值(包括null)

obj?.__proto__ === Object.prototype

or

obj?.constructor.name === 'Object';

我喜欢简单地:

function isObject (item) {
  return (typeof item === "object" && !Array.isArray(item) && item !== null);
}

如果该项是一个JS对象,并且它不是一个JS数组,并且它不为空……如果这三个都是真的,则返回true。如果三个条件中的任何一个失败,&&测试将短路,并返回false。如果需要,可以省略null测试(取决于如何使用null)。

文档:

http://devdocs.io/javascript/operators/typeof

http://devdocs.io/javascript/global_objects/object

http://devdocs.io/javascript/global_objects/array/isarray

http://devdocs.io/javascript/global_objects/null

我认为有这么多答案的原因是,无论你是否喜欢,很多东西都是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')
    // ...

这取决于用例,如果我们不想让数组和函数成为Object,我们可以使用undercore.js内置函数。

    function xyz (obj) { 
       if (_.isObject(obj) && !_.isFunction(obj) && !_.isArray(obj)) {
         // now its sure that obj is an object 
       } 
    }

如果明确希望检查给定值是否为{}。

function isObject (value) {
 return value && typeof value === 'object' && value.constructor === Object;
}