检查值是否是JavaScript中的对象

时间:2011-12-14 20:35:47

标签: javascript object types javascript-objects

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

48 个答案:

答案 0 :(得分:1255)

如果typeof yourVariable === 'object',它是一个对象或null。如果要排除null,只需将其设为typeof yourVariable === 'object' && yourVariable !== null

答案 1 :(得分:483)

让我们在Javascript中定义“对象”。根据{{​​3}},每个值都是对象或原语:

  

原始,原始价值

     

不是对象且没有任何方法的数据。 JavaScript有5种原始数据类型:string,number,boolean,null,undefined。

什么是原始的?

  • 3
  • 'abc'
  • true
  • null
  • undefined

什么是对象(即不是原始对象)?

  • Object.prototype
  • 来自Object.prototype的一切
    • Function.prototype
      • Object
      • Function
      • function C(){} - 用户定义的函数
    • C.prototype - 用户定义函数的prototype属性:这是 not C的原型
      • new C() - “新” - 用户定义的函数
    • 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 docs

  

Object构造函数为给定值创建一个对象包装器。如果值为null或未定义,则它将创建并返回空对象,否则,它将返回与给定值对应的类型的对象。如果该值已经是一个对象,它将返回该值。


第三种似乎有用的方法(不确定它是否为100%)是使用Object.getPrototypeOf MDN docs如果它的参数不是对象:

// 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({})

答案 2 :(得分:420)

尝试使用typeof(var)和/或var instanceof something

编辑:这个答案给出了如何检查变量属性的想法,但它是一个防弹配方(毕竟根本没有配方!)来检查它是否是一个对象,远离它。由于人们倾向于在没有进行任何研究的情况下从这里寻找要复制的东西,我强烈建议他们转向另一个,最受欢迎(并且正确!)的答案。

答案 3 :(得分:235)

官方underscore.js使用此检查来确定某些内容是否真的是一个对象

// Is a given variable an object?
_.isObject = function(obj) {
  return obj === Object(obj);
};

<强>更新

由于V8中的先前错误和次要微速度优化,updated underscore.js库现在正在使用以下内容。

// Is a given variable an object?
_.isObject = function(obj) {
  var type = typeof obj;
  return type === 'function' || type === 'object' && !!obj;
};

答案 4 :(得分:165)

Object.prototype.toString.call(myVar)将返回:

  • "[object Object]"如果myVar是一个对象
  • "[object Array]"如果myVar是数组

有关这方面的更多信息以及为什么它是typeof的一个很好的替代方法check out this article

答案 5 :(得分:88)

仅用于检查对象或数组而无需额外的函数调用(速度)。同时发布了here

<强> 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

isObject() - 注意:仅用于Object文字,因为它为自定义对象返回false,例如new Date或new YourCustomObject。

isObject = function(a) {
    return (!!a) && (a.constructor === Object);
};
console.log(isObject(        )); // false
console.log(isObject(    null)); // false
console.log(isObject(    true)); // false
console.log(isObject(       1)); // false
console.log(isObject(   'str')); // false
console.log(isObject(      [])); // false
console.log(isObject(new Date)); // false
console.log(isObject(      {})); // true

答案 6 :(得分:71)

我很喜欢这个:

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

如果该项是JS对象,并且它不是JS数组,并且它不是null ...如果所有三个都证明是真的,则返回true。如果三个条件中的任何一个失败,&&测试将发生短路,并返回false。如果需要,可以省略null测试(取决于您使用null的方式)。

DOCS:

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

答案 7 :(得分:67)

使用函数Array.isArray

function isObject(o) {
  return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}

没有函数Array.isArray

对于有多少赞成错误的答案感到惊讶
只有1 answer通过了我的考试!在这里,我创建了我的简化版本:

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

结果,您将拥有严格而强大的代码!

如果您不创建isDateisErrorisRegExp等功能,您可以考虑使用此通用功能的选项:

function isObject(o) {
  return o instanceof Object && typeof o.constructor === 'function';
}

对于前面提到的所有测试用例,它都无法正常工作,但它对所有对象(普通或构造)都足够好。

isObjectObject.create(null)的情况下不起作用,因为Object.create的内部实施已解释为here,但您可以使用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;
};

基于此实现已经创建了package on npm v1!它适用于所有早期描述的测试用例!

答案 8 :(得分:28)

好的,在回答你的问题之前,让我们首先给你这个概念,在JavaScript函数是对象,也是null,对象,数组甚至日期,所以你看到有这样的简单方法typeof obj ==='object',所以上面提到的所有内容都会返回true ,但有办法通过编写函数或使用JavaScript框架来检查它,OK:

现在,假设你有这个对象是一个真实的对象(不是null或函数或数组):

var obj = {obj1: 'obj1', obj2: 'obj2'};

Pure JavaScript:

//that's how it gets checked in angular framework
function isObject(obj) {
  return obj !== null && typeof obj === 'object';
}

//make sure the second object is capitalised 
function isObject(obj) {
   return Object.prototype.toString.call(obj) === '[object Object]';
}

function isObject(obj) {
    return obj.constructor.toString().indexOf("Object") > -1;
}

function isObject(obj) {
    return obj instanceof Object;
}

您可以通过调用它们在代码中使用上述函数中的一个,如果它是一个对象,它将返回true:

isObject(obj);

如果您使用的是JavaScript框架,他们通常会为您准备这些功能,这些功能很少:

jQuery:

 //It returns 'object' if real Object;
 jQuery.type(obj);

角:

angular.isObject(obj);

下划线和Lodash:

//(NOTE: in Underscore and Lodash, functions, arrays return true as well but not null)
_.isObject(obj);

答案 9 :(得分:22)

这取决于你对“是一个对象”的意思。如果你想要所有不是原语的东西,即你可以设置新属性的东西,这应该可以解决问题:

function isAnyObject(value) {
    return value != null && (typeof value === 'object' || typeof value === 'function');
}

它排除了原语(普通数字/ NaN / Infinity,普通字符串,符号,true / falseundefined和{{1}但是应该为其他所有内容返回true(包括nullNumberBoolean个对象)。请注意,JS没有定义与String一起使用时应返回的“主机”对象,例如windowconsole,因此很难用这样的支票覆盖。< / p>

如果您想知道某些内容是否是“普通”对象,即它是以文字typeof还是{}创建的,您可以这样做:

Object.create(null)

编辑2018 :由于Symbol.toStringTag现在允许自定义function isPlainObject(value) { if (Object.prototype.toString.call(value) !== '[object Object]') { return false; } else { var prototype = Object.getPrototypeOf(value); return prototype === null || prototype === Object.prototype; } } 的输出,因此上述Object.prototype.toString.call(...)函数在某些情况下可能会返回isPlainObject当对象以文字开头时。可以说,按照惯例,具有自定义字符串标记的对象不再是一个普通对象,但这进一步混淆了普通对象在Javascript中的定义。

答案 10 :(得分:16)

我的上帝,其他答案太混乱了。

简短回答

typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array)

要对此进行测试,只需在chrome控制台中运行以下语句即可。

案例1。

var anyVar = {};
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // true

案例2。

anyVar = [];
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array) // false

案例3。

anyVar = null;
typeof anyVar == 'object' && anyVar instanceof Object && !(anyVar instanceof Array); // false

说明

好的。让我们分解一下

typeof anyVar == 'object'从三个候选者-[], {} and null中返回true,

anyVar instanceof Object将这些候选对象缩小为两个-[], {}

!(anyVar instanceof Array)缩小到一个-{}

请打鼓!

到此,您可能已经学习了如何在Javascript中检查数组。

答案 11 :(得分:16)

检查值类型的最合理方法似乎是typeof运算符。唯一的问题是,它可怕地被打破了:

  • 它返回"object" null,属于Null类型。
  • 它为可调用对象返回"function",它们属于对象类型。
  • 它可以返回(几乎)任何它想要的非标准非可调用对象。例如,IE似乎喜欢"unknown"。唯一禁止的结果是"function"和原始类型。

typeof仅对非null基元可靠。因此,检查值是否为对象的方法是确保typeof返回的字符串不对应于基元,并且该对象不是null。然而,问题在于未来的标准可能会引入一种新的基本类型,而我们的代码会认为它是一个对象。新类型不经常出现,但例如ECMAScript 6引入了Symbol类型。

因此,我只推荐其结果因值是否为对象而变化的方法,而不是typeof。以下打算成为

测试某个值是否属于Object类型的正确方法的全面但非详尽的列表。

  • Object构造函数

    Object构造函数强制传递给对象的参数。如果它已经是对象,则返回相同的对象。

    因此,您可以使用它来强制对象的值,并严格地将该对象与原始值进行比较。

    以下函数需要ECMAScript 3,它引入了===

    function isObject(value) { /* Requires ECMAScript 3 or later */
      return Object(value) === value;
    }
    

    我喜欢这种方法,因为它简单且具有自我描述性,类似的检查也适用于布尔值,数字和字符串。但是,请注意它依赖于全局Object不被遮蔽或改变。<​​/ p>

  • <强>构造

    实例化构造函数时,它可以返回与刚创建的实例不同的值。但除非它是一个对象,否则该值将被忽略。

    以下函数需要ECMAScript 3,它允许构造函数返回非对象。在ECMAScript 3之前发生了错误,但当时没有try语句存在。

    function isObject(value) { /* Requires ECMAScript 3 or later */
      return new function() { return value; }() === value;
    }
    

    虽然比上一个例子简单一点,但这个不依赖于任何全局属性,因此可能是最安全的。

  • this

    旧的ECMAScript规范要求this值为对象。 ECMAScript 3引入了Function.prototype.call,允许调用具有任意this值的函数,但强制转换为对象。

    ECMAScript 5引入了一种严格模式,删除了这种行为,但在草率模式下,我们仍然可以(但可以说不应该)依赖它。

    function isObject(value) { /* Requires ECMAScript 3 or later in sloppy mode */
      return function() { return this === value; }.call(value);
    }
    
  • <强> [[原型]]

    所有普通对象都有一个名为[[Prototype]]的内部插槽,其值决定了它从哪个其他对象继承。该值只能是对象或null。因此,您可以尝试创建一个继承所需值的对象,并检查它是否有效。

    Object.createObject.getPrototypeOf都需要ECMAScript 5。

    function isObject(value) { /* Requires ECMAScript 5 or later */
      try {
        Object.create(value);
        return value !== null;
      } catch(err) {
        return false;
      }
    }
    
    function isObject(value) { /* Requires ECMAScript 5 or later */
      function Constructor() {}
      Constructor.prototype = value;
      return Object.getPrototypeOf(new Constructor()) === value;
    }
    
  • 一些新的ECMAScript 6方法

    ECMAScript 6引入了一些新的间接方法来检查一个值是一个对象。他们使用先前看到的方法将值传递给某些需要对象的代码,该代码包含在try语句中以捕获错误。一些隐藏的例子,不值得评论

    &#13;
    &#13;
    function isObject(value) { /* Requires ECMAScript 6 or later */
      try {
        Object.setPrototypeOf({}, value);
        return value !== null;
      } catch(err) {
        return false;
      }
    }
    &#13;
    &#13;
    &#13;

    &#13;
    &#13;
    function isObject(value) { /* Requires ECMAScript 6 or later */
      try {
        new WeakSet([value]);
        return true;
      } catch(err) {
        return false;
      }
    }
    &#13;
    &#13;
    &#13;

注意:我故意跳过一些方法,如Object.getPrototypeOf(value)(ES5)和Reflect方法(ES6),因为它们调用了必要的内部方法,这些方法可能会产生令人讨厌的事情,例如如果value是代理人。出于安全原因,我的示例仅引用value而不直接访问它。

答案 12 :(得分:14)

试试这个

if (objectName instanceof Object == false) {
  alert('Not an object');
}
else {
  alert('An object');
}

答案 13 :(得分:14)

我的天哪!我认为这可能比以往任何时候都更短,让我们看看:

短代码和最终代码

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简介

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

  

注意:自2018年起,Function.name可能在 IE https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility

中不起作用

答案 14 :(得分:12)

准备使用功能进行检查

function isObject(o) {
  return null != o && 
    typeof o === 'object' && 
    Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
  return !isObject(o) && 
    null != o && 
    (typeof o === 'object' || typeof o === 'function') &&
    /^\[object /.test(Object.prototype.toString.call(o));
}

// Loose equality operator (==) is intentionally used to check
// for undefined too

// Also note that, even null is an object, within isDerivedObject
// function we skip that and always return false for null

解释

  • 在Javascript中,nullObjectArrayDatefunction都是对象。虽然,null有点人为。因此,最好首先检查null,以检测它是否为空。

  • 检查typeof o === 'object'是否保证o是一个对象。如果没有这个检查,Object.prototype.toString将毫无意义,因为即使对于undefinednull,它也会返回对象以进行翻转!例如:toString(undefined)返回[object Undefined]

    typeof o === 'object'检查之后,toString.call(o)是检查o是否为对象,派生对象(如ArrayDate还是function

  • isDerivedObject函数中,它检查o是否为函数。因为,功能也是一个对象,这就是为什么它在那里。如果没有这样做,函数将返回false。示例:isDerivedObject(function() {})将返回false,但现在返回true

  • 可以随时更改对象的定义。因此,可以相应地更改这些功能。

测试

function isObject(o) {
  return null != o && 
    typeof o === 'object' && 
    Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
  return !isObject(o) && 
    null != o && 
    (typeof o === 'object' || typeof o === 'function') &&
    /^\[object /.test(Object.prototype.toString.call(o));
}

// TESTS

// is null an object?

console.log(
  'is null an object?', isObject(null)
);

console.log(
  'is null a derived object?', isDerivedObject(null)
);

// is 1234 an object?

console.log(
  'is 1234 an object?', isObject(1234)
);

console.log(
  'is 1234 a derived object?', isDerivedObject(1234)
);

// is new Number(1234) an object?

console.log(
  'is new Number(1234) an object?', isObject(new Number(1234))
);

console.log(
  'is new Number(1234) a derived object?', isDerivedObject(1234)
);

// is function object an object?

console.log(
  'is (new (function (){})) an object?', 
  isObject((new (function (){})))
);

console.log(
  'is (new (function (){})) a derived object?', 
  isObject((new (function (){})))
);

// is {} an object?

console.log(
  'is {} an object?', isObject({})
);

console.log(
  'is {} a derived object?', isDerivedObject({})
);

// is Array an object?

console.log(
  'is Array an object?',
  isObject([])
)

console.log(
  'is Array a derived object?',
  isDerivedObject([])
)

// is Date an object?

console.log(
  'is Date an object?', isObject(new Date())
);

console.log(
  'is Date a derived object?', isDerivedObject(new Date())
);

// is function an object?

console.log(
  'is function an object?', isObject(function(){})
);

console.log(
  'is function a derived object?', isDerivedObject(function(){})
);

答案 15 :(得分:11)

var a = [1]
typeof a //"object"
a instanceof Object //true
a instanceof Array //true

var b ={a: 1}
b instanceof Object //true
b instanceof Array //false

var c = null
c instanceof Object //false
c instanceof Array //false

我被要求提供更多细节。检查变量是否为对象的最清晰且易于理解的方法是typeof myVar。它返回一个带有类型的字符串(例如"object""undefined")。

不幸的是,Array和null也有类型object。要仅使用真实对象,需要使用instanceof运算符检查继承链。它将消除null,但Array在继承链中具有Object。

所以解决方案是:

if (myVar instanceof Object && !(myVar instanceof Array)) {
  // code for objects
}

答案 16 :(得分:10)

迟到了......对于“普通物体”(我的意思是,像{'x':5,'y':7})我有这个小片段:

function isPlainObject(o) {
   return ((o === null) || Array.isArray(o) || typeof o == 'function') ?
           false
          :(typeof o == 'object');
}

它会生成下一个输出:

console.debug(isPlainObject(isPlainObject)); //function, false
console.debug(isPlainObject({'x': 6, 'y': 16})); //literal object, true
console.debug(isPlainObject(5)); //number, false
console.debug(isPlainObject(undefined)); //undefined, false
console.debug(isPlainObject(null)); //null, false
console.debug(isPlainObject('a')); //string, false
console.debug(isPlainObject([])); //array?, false
console.debug(isPlainObject(true)); //bool, false
console.debug(isPlainObject(false)); //bool, false

它总是适合我。如果“o”的类型是“object”但是没有null,数组或函数,则返回“true”。 :)

答案 17 :(得分:8)

由于对如何正确处理此问题似乎有很多困惑,我将留下2美分(此答案符合规范,并在所有情况下均能产生正确的结果):

测试原语: undefined null boolean string number

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['Float32Array']=true;
    arrayTypes['Float64Array']=true;
    return function(o){
        if (!o) return false;
        return !isPrimitive(o)&&!!arrayTypes[o.constructor.name];
    }
}());

测试对象是否排除:Date RegExp Boolean Number String Function任何数组

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];
    }
}());

答案 18 :(得分:8)

这会奏效。它是一个返回true,false或可能为null的函数。

const isObject = obj => obj && obj.constructor && obj.constructor === Object;

console.log(isObject({})); // true
console.log(isObject([])); // false
console.log(isObject(new Function)); // false
console.log(isObject(new Number(123))); // false
console.log(isObject(null)); // null

答案 19 :(得分:8)

lodash有isPlainObject,这可能是许多访问此页面的人正在寻找的内容。在给出函数或数组时它返回false。

答案 20 :(得分:7)

在阅读并尝试了许多实现之后,我注意到很少有人尝试检查诸如JSONMathdocument之类的值或原型链较长的对象超过1步。

我认为最好是将检查保持尽可能简单,以免在有新的原语或本机时需要重构,而不是先检查变量的typeof然后破解边缘情况。添加的对象注册为“对象”的typeof

毕竟,typeof运算符会告诉您是否是JavaScript的对象,但是JavaScript对对象的定义对于大多数现实情况而言(例如{{ 1}})。 下面是一个函数,该函数通过本质上重复两次检查来确定变量typeof null === 'object'是否为对象:

  1. 只要v的字符串化版本为v,循环就会开始。
    我希望函数的结果与下面的日志完全一样,所以这是我最后得到的唯一“对象”条件。如果失败,该函数将立即返回false。
  2. '[object Object]'v替换为链中的下一个原型,但之后也被直接评估。当v = Object.getPrototypeOf(v)的新值为v时,表示每个原型,包括根原型(很可能是 only 原型在链中)已通过while循环中的检查,我们可以返回true。否则,将开始新的迭代。

null

答案 21 :(得分:7)

当其他一切都失败时,我用这个:

var isObject = function(item) {
   return item.constructor.name === "Object";
}; 

答案 22 :(得分:7)

Ramda函数库具有检测JavaScript类型的出色功能。

解释full function

function type(val) {
  return val === null      ? 'Null'      :
         val === undefined ? 'Undefined' :
         Object.prototype.toString.call(val).slice(8, -1);
}
当我意识到解决方案的简单和美观时,我不得不笑。

Ramda documentation的使用示例:

R.type({}); //=> "Object"
R.type(1); //=> "Number"
R.type(false); //=> "Boolean"
R.type('s'); //=> "String"
R.type(null); //=> "Null"
R.type([]); //=> "Array"
R.type(/[A-z]/); //=> "RegExp"
R.type(() => {}); //=> "Function"
R.type(undefined); //=> "Undefined"

答案 23 :(得分:6)

出于我的代码的目的,我找到了与上述某些答案相对应的决定:

ES6变体:

const checkType = o => Object.prototype
                    .toString
                    .call(o)
                    .replace(/\[|object\s|\]/g, '')
                    .toLowerCase();

ES5变体:

function checkType(o){
   return Object.prototype
                    .toString
                    .call(o)
                    .replace(/\[|object\s|\]/g, '')
                    .toLowerCase();
}

您可以非常简单地使用它:

checkType([]) === 'array'; // true
checkType({}) === 'object'; // true
checkType(1) === 'number'; // true
checkType('') === 'string'; // true
checkType({}.p) === 'undefined'; // true
checkType(null) === 'null'; // true

以此类推。

答案 24 :(得分:6)

if(typeof value === 'object' && value.constructor === Object)
{
    console.log("This is an object");
}

答案 25 :(得分:5)

function isObjectLike(value) {
  return value != null && typeof value == 'object';
}

lodash获得

答案 26 :(得分:5)

  var isObject = function(obj) {
    var type = typeof obj;
    return type === 'function' || type === 'object' && !!obj;
  };

!!obj是检查对象是否真实的简写(过滤掉null / undefined)

答案 27 :(得分:4)

我喜欢使用的是

function isObject (obj) {
  return typeof(obj) == "object" 
        && !Array.isArray(obj) 
        && obj != null 
        && obj != ""
        && !(obj instanceof String)  }

我认为在大多数情况下,Date必须将支票作为对象传递,因此我不会过滤日期

答案 28 :(得分:4)

性能

今天2020.09.26我针对选定的解决方案在Chrome v85,Safari v13.1.2和Firefox v80的MacOs HighSierra 10.13.6上进行了测试。

结果

  • 在所有情况下,解决方案C和H在所有浏览器中都是最快/最快的
  • 在所有情况下,解决方案D和G在所有浏览器中的速度都是最慢/最慢的

enter image description here

详细信息

我为解决方案执行3个测试案例 A B C D E F G H I J K L M N O P Q R S T U V

  • 对于小对象-您可以HERE运行它
  • 对于大对象-您可以HERE运行它
  • 无对象-您可以HERE运行

以下代码段显示了解决方案之间的差异。解决方案A-G针对Matt Fenwick

描述的选定情况给出正确答案

// https://stackoverflow.com/a/14706877/860099
function A(x) {
  return x === Object(x);
};

// https://stackoverflow.com/a/42250981/860099
function B(x) {
    return _.isObject(x);
}

// https://stackoverflow.com/a/34864175/860099
function C(x) {
    return x != null && (typeof x === 'object' || typeof x === 'function');
}

// https://stackoverflow.com/a/39187058/860099
function D(x) { 
  return new function() { return x; }() === x;
}

// https://stackoverflow.com/a/39187058/860099
function E(x) { 
  return function() { return this === x; }.call(x);
}

// https://stackoverflow.com/a/39187058/860099
function F(x) { /* Requires ECMAScript 5 or later */
  try {
    Object.create(x);
    return x !== null;
  } catch(err) {
    return false;
  }
}

// https://stackoverflow.com/a/39187058/860099
function G(x) { /* Requires ECMAScript 5 or later */
  function Constructor() {}
  Constructor.prototype = x;
  return Object.getPrototypeOf(new Constructor()) === x;
}

// https://stackoverflow.com/a/8511332/860099
function H(x) {
  return typeof x === 'object' && x !== null
}

// https://stackoverflow.com/a/25715455/860099
function I(x) {
  return (typeof x === "object" && !Array.isArray(x) && x !== null);
};

// https://stackoverflow.com/a/22482737/860099
function J(x) {
  return x instanceof Object; 
}

// https://stackoverflow.com/a/50712057/860099
function K(x)
{
    let t= JSON.stringify(x);
    return t ? t[0] === '{' : false;
}

// https://stackoverflow.com/a/13356338/860099
function L(x) {
  return Object.prototype.toString.call(x) === "[object Object]";
};



// https://stackoverflow.com/a/46663081/860099
function M(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;
}

// https://stackoverflow.com/a/42250981/860099
function N(x) {
    return $.type(x) === 'object';
}

// https://stackoverflow.com/a/34864175/860099
function O(x) {
    if (Object.prototype.toString.call(x) !== '[object Object]') {
        return false;
    } else {
        var prototype = Object.getPrototypeOf(x);
        return prototype === null || prototype === Object.prototype;
    }
}

// https://stackoverflow.com/a/57863169/860099
function P(x) {
  while (     Object.prototype.toString.call(x) === '[object Object]')
  if    ((x = Object.getPrototypeOf(x))         === null)
  return true
  return false
}

// https://stackoverflow.com/a/43289971/860099
function Q(x){
  try{
    switch(x.constructor){
      case Number:
      case Function:
      case Boolean:
      case Symbol:
      case Date:
      case String:
      case RegExp:
        return x.constructor === Object;
      case Error:
      case EvalError:
      case RangeError:
      case ReferenceError:
      case SyntaxError:
      case TypeError:
      case URIError:
        return (Object === Error ? Error : x.constructor) === Object;
      case Array:
      case Int8Array:
      case Uint8Array:
      case Uint8ClampedArray:
      case Int16Array:
      case Uint16Array:
      case Int32Array:
      case Uint32Array:
      case Float32Array:
      case Float64Array:
        return (Object === Array ? Array : x.constructor) === Object;
      case Object:
      default:
        return (Object === Object ? Object : x.constructor) === Object;
    }
  } catch(ex){
    return x == Object;   
  }
}

// https://stackoverflow.com/a/52478680/860099
function R(x) {
    return typeof x == 'object' && x instanceof Object && !(x instanceof Array);
}

// https://stackoverflow.com/a/51458052/860099
function S(x)
{
    return x != null && x.constructor?.name === "Object"
}

// https://stackoverflow.com/a/42250981/860099
function T(x) {
    return x?.constructor?.toString().indexOf("Object") > -1;
}

// https://stackoverflow.com/a/43223661/860099
function U(x)
{
    return x?.constructor === Object;
}

// https://stackoverflow.com/a/46663081/860099
function V(x) {
  return x instanceof Object && x.constructor === Object;
}




// -------------
// TEST
// -------------

console.log('column: 1 2 3 4 5 6 - 7 8 9 10 11');

[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V]
.map(f=> console.log(`${f.name}:      ${1*f(new Date())} ${1*f(/./)} ${1*f({})} ${1*f(Object.prototype)} ${1*f(Object.create(null))} ${1*f(()=>{})} - ${1*f("abc")} ${1*f(3)} ${1*f(true)}  ${1*f(null)}  ${1*f(undefined)}`))

console.log(`
Columns legend (test cases):
 1: new Date()
 2: /./ (RegExp)
 3: {}
 4: Object.prototype
 5: Object.create(null)
 6: ()=>{} (function)
 7: "abc" (string)
 8: 3 (number)
 9: true (boolean)
10: null
11: undefined

Rows:
1 = is object
0 = is NOT object

Theoretically columns 1-6 should have have 1, columns 7-11 shoud have 0
`);
<script
  src="https://code.jquery.com/jquery-3.5.1.min.js"
  integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
  crossorigin="anonymous"></script>
  
<script 
  src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" 
  integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" 
  crossorigin="anonymous"></script>
  
This shippet only presents functions used in performance tests - it not perform tests itself!

这是铬的示例结果

enter image description here

答案 29 :(得分:4)

如果您想检查prototype的{​​{1}}是否仅来自object。过滤掉ObjectStringNumberArray

Arguments

答案 30 :(得分:3)

我找到了一个新的&#34;从这个SO问题做这种类型检查的方法:Why does instanceof return false for some literals?

从那以后,我创建了一个类型检查函数,如下所示:

function isVarTypeOf(_var, _type){
    try {
        return _var.constructor === _type;
    } catch(ex) {
        return false;         //fallback for null or undefined
    }
}

那么你可以这样做:

console.log(isVarTypeOf('asdf', String));   // returns true
console.log(isVarTypeOf(new String('asdf'), String));   // returns true
console.log(isVarTypeOf(123, String));   // returns false
console.log(isVarTypeOf(123, Number));   // returns true
console.log(isVarTypeOf(new Date(), String));   // returns false
console.log(isVarTypeOf(new Date(), Number));   // returns false
console.log(isVarTypeOf(new Date(), Date));   // returns true
console.log(isVarTypeOf([], Object));   // returns false
console.log(isVarTypeOf([], Array));   // returns true
console.log(isVarTypeOf({}, Object));   // returns true
console.log(isVarTypeOf({}, Array));   // returns false
console.log(isVarTypeOf(null, Object));   // returns false
console.log(isVarTypeOf(undefined, Object));   // returns false
console.log(isVarTypeOf(false, Boolean));   // returns true

这是在Chrome 56,Firefox 52,Microsoft Edge 38,Internet Explorer 11,Opera 43

上测试的

修改
如果您还想检查变量是否为null或未定义,则可以改为使用:

function isVarTypeOf(_var, _type){
    try {
        return _var.constructor === _type;
    } catch(ex) {
        return _var == _type;   //null and undefined are considered the same
        // or you can use === if you want to differentiate them
    }
}

var a = undefined, b = null;
console.log(isVarTypeOf(a, undefined)) // returns true
console.log(isVarTypeOf(b, undefined)) // returns true
console.log(isVarTypeOf(a, null)) // returns true

从inanc的评论中更新:接受挑战:D

如果您想要丢失比较对象,可以尝试这种方式:

function isVarTypeOf(_var, _type, looseCompare){
    if (!looseCompare){
        try {
            return _var.constructor === _type;
        } catch(ex){
            return _var == _type;
        }
    } else {
        try{
            switch(_var.constructor){
                case Number:
                case Function:
                case Boolean:
                case Symbol:
                case Date:
                case String:
                case RegExp:
                    // add all standard objects you want to differentiate here
                    return _var.constructor === _type;
                case Error:
                case EvalError:
                case RangeError:
                case ReferenceError:
                case SyntaxError:
                case TypeError:
                case URIError:
                    // all errors are considered the same when compared to generic Error
                    return (_type === Error ? Error : _var.constructor) === _type;
                case Array:
                case Int8Array:
                case Uint8Array:
                case Uint8ClampedArray:
                case Int16Array:
                case Uint16Array:
                case Int32Array:
                case Uint32Array:
                case Float32Array:
                case Float64Array:
                    // all types of array are considered the same when compared to generic Array
                    return (_type === Array ? Array : _var.constructor) === _type;
                case Object:
                default:
                    // the remaining are considered as custom class/object, so treat it as object when compared to generic Object
                    return (_type === Object ? Object : _var.constructor) === _type;
            }
        } catch(ex){
            return _var == _type;   //null and undefined are considered the same
            // or you can use === if you want to differentiate them
        }
    }
}
就这样,你可以像inanc的评论那样做:

isVarTypeOf(new (function Foo(){}), Object); // returns false
isVarTypeOf(new (function Foo(){}), Object, true); // returns true

Foo = function(){};
Bar = function(){};
isVarTypeOf(new Foo(), Object);   // returns false
isVarTypeOf(new Foo(), Object, true);   // returns true
isVarTypeOf(new Bar(), Foo, true);   // returns false
isVarTypeOf(new Bar(), Bar, true);   // returns true
isVarTypeOf(new Bar(), Bar);    // returns true

答案 31 :(得分:3)

如果明确想检查给定值是否为{}

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

答案 32 :(得分:2)

考虑-typeof bar === "object"确定bar是否是对象

尽管typeof bar === "object"是检查bar是否为对象的可靠方法,但是JavaScript中令人惊讶的陷阱是null也被视为对象!

因此,以下代码会让大多数开发人员感到惊讶,将true(不是false)记录到控制台:

var bar = null; console.log(typeof bar === "object"); // logs true! 只要知道这一点,也可以通过检查bar是否为空来轻松避免该问题:

console.log((bar !== null) && (typeof bar === "object")); // logs false 为了使我们的回答更加彻底,还有两点值得注意:

首先,如果bar是一个函数,则上述解决方案将返回false。在大多数情况下,这是理想的行为,但是在您还希望对函数返回true的情况下,可以将上述解决方案修改为:

console.log((bar !== null) && ((typeof bar === "object") || (typeof bar === "function"))); 其次,如果bar是数组(例如,如果var bar = [];),则上述解决方案将返回true。在大多数情况下,这是理想的行为,因为数组确实是对象,但是在您还希望对数组也为假的情况下,可以将上述解决方案修改为:

console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]")); 但是,还有另一种选择,对于null,数组和函数,返回false;对于对象,返回true:

console.log((bar !== null) && (bar.constructor === Object)); 或者,如果您使用的是jQuery:

console.log((bar !== null) && (typeof bar === "object") && (! $.isArray(bar)));

ES5使数组的大小写非常简单,包括它自己的null检查:

console.log(Array.isArray(bar));

答案 33 :(得分:1)

大多使用typeof obj[index] === 'object',但它也会返回function#document作为对象。如果需要将其包括在结果中,则取决于您。

基本上,您可以通过检查控制台中的输出来执行过滤掉特定元素是否为对象的测试代码。在这里,您只需为样本运行代码:

&#13;
&#13;
function cekObject(obj, index) {  
  if (!obj.tagName) {

    //test case #1      
    if (typeof obj === 'object') {
      console.log('obj['+ index +'] is listed as an object');
    }	
    
  }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<script>
  function updateFilters() {
    var object = $('.j-image');
    $('.juicer-feed').empty();
    
    for(var index in object) {
      cekObject(object[index], index);
    }; 
  }
</script>

<ul class="juicer-feed" data-feed-id="chetabahana" data-after="updateFilters()"></ul>
<script src="https://assets.juicer.io/embed.js"></script>
&#13;
&#13;
&#13;

答案 34 :(得分:1)

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

&#13;
&#13;
var test = {}
if(JSON.stringify(test)[0] === '{') {
  console.log('this is a Object')
}
&#13;
&#13;
&#13;

答案 35 :(得分:1)

它取决于用例,如果我们不想允许数组和函数成为Object,我们可以使用underscore.js内置函数。

const theme = createMuiTheme({
  palette: {
    primary: lime,
    secondary: {
      ...grey,
      A400: '#00e677'
    },
    error: red
  }
});

class App extends Component {

  render() {
    const classes = this.props.classes;

    return (
      <div className={classes.root}>
        <MuiThemeProvider theme={theme}>
          <MyApp/>
        </MuiThemeProvider>
      </div>

    );
  }


  }

  export default withStyles(styles)(App);

答案 36 :(得分:1)

这是一个古老的问题,但被认为应该留在这里。大多数人都在检查变量是否为{}表示键值配对,而不是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返回的数据库调用。然后我们可以测试是否不是Array,不是null,不是typeof 'function'和是Object

!Array.isArray(x) && x !== null && x === Object(x) && typeof x !== 'function'

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 = {} // true

答案 37 :(得分:1)

如果您已经在使用AngularJS,那么它有一个内置方法,它将检查它是否是一个对象(不接受null)。

angular.isObject(...)

答案 38 :(得分:1)

确定变量是否为对象的最简单方法:

首先:评估对象的类型

秒:从对象获取Array属性必须返回undefined(例如length是一个不适用于Object的Array属性)

如此:

if (_object instanceof Object && _object.length === undefined) {
// here you can be sure that you have a curly bracket object :)
}

答案 39 :(得分:1)

这很棘手,因为数组是对象类型,函数是对象类型,实际对象{}也是对象输入

问题

const arr = []
const fun = function(){}
const actualObj = {}

arr instanceof Object // true
fun instanceof Object // true
actualObj instanceof Object // true

所以目标是actualObj 必须返回true,其他一切都必须返回false

actualObj instanceof Object && !(actualObj instanceof Array) && !(typeof actualObj === 'function') // true

答案 40 :(得分:0)

使用typeof(my_obj)将告诉它是哪种类型的变量。

for Array: Array.isArray(inp)[] isinstanceof Array

如果它是对象将显示'对象'

简单的JS功能,

function isObj(v) {
    return typeof(v) == "object"
}

<强>例如

function isObj(v) {
    return typeof(v) == "object"
}

var samp_obj = {
   "a" : 1,
   "b" : 2,
   "c" : 3
}

var num = 10;
var txt = "Hello World!"
var_collection = [samp_obj, num, txt]
for (var i in var_collection) {
  if(isObj(var_collection[i])) {
     console.log("yes it is object")
  }
  else {
     console.log("No it is "+ typeof(var_collection[i]))
  }
}

答案 41 :(得分:0)

记住typeof new Date()"object"的人。

因此,如果您要寻找{ key: value }对象,则日期对象无效。

最后,我认为o => o && typeof o === 'object' && !(o instanceof Date)是对您问题的更好答案。

答案 42 :(得分:-1)

我知道它已经很旧了,但是如果您不关心财产定单,我确实认为此解决方案很有趣:

function objectsDeeplyEqual(obj1, obj2) {
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  let equal = true;
  if (keys1.length !== keys2.length) {
    return false;
  }
  for (let i = 0; i < keys1.length && equal; i++) {
    if (obj1[keys1[i]] instanceof Object && obj2[keys1[i]] instanceof Object) {
      equal = equal && isDeeplyEqual(obj1[keys1[i]], obj2[keys1[i]]);
    } else {
      equal = equal && obj1[keys1[i]] === obj2[keys1[i]];
    }
  }
  return equal;
}

var a = {
  a: true,
  b: 'asd',
  c: {
    a: true,
    b: 'asd',
    c: {
      a: true,
      b: 'asd',
    },
  },
};

var b = {
  a: true,
  c: {
    a: true,
    b: 'asd',
    c: {
      a: true,
      b: 'asd',
    },
  },
  b: 'asd',
};

console.log(isDeeplyEqual(a,b));
console.log(isDeeplyEqual(b,a));

答案 43 :(得分:-3)

一个小的NodeJS控制台实验,基于Matt Fenwick对上面完整答案的第三个选项的阅读。只需稍加调整即可获得truefalse

以下为对象测试返回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

答案 44 :(得分:-3)

您可以使用 Object.prototype

toString()方法轻松完成此操作
if(Object.prototype.toString.call(variable) == "[object Object]"){
   doSomething();
}

if(Object.prototype.toString.call(variable).slice(8,-1).toLowerCase() == "object"){
   doSomething();
}

答案 45 :(得分:-3)

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

答案 46 :(得分:-4)

直接回答当然是setVisibility(VISIBLE),但这非常有用。我想知道OP是否意味着一本普通的字典..

尝试:

typeof v==='object'

答案 47 :(得分:-5)

我有一个有效的代码段。我发现在没有给出整段代码时会让人感到困惑,所以我自己创建了它:

    <!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>