检查值是否是 JavaScript 中的对象

如何检查值是否是 JavaScript 中的 Object?

答案

如果typeof yourVariable === 'object'typeof yourVariable === 'object'对象或 null。如果要排除 null,请将其类型设置为typeof yourVariable === 'object' && yourVariable !== null

让我们在 Javascript 中定义 “对象” 。根据MDN docs ,每个值都是对象或基元:

原始的原始值

不是对象且没有任何方法的数据。 JavaScript 具有 5 种原始数据类型:字符串,数字,布尔值,空值,未定义。

什么是原始语?

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

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

  • Object.prototype
  • 一切都源自Object.prototype
    • Function.prototype
      • Object
      • Function
      • function C(){} - 用户定义的函数
    • C.prototype用户定义函数的 prototype 属性:这不是 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 文档

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


似乎可行的第三种方法(不确定是否为 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({})

更新

这个答案是不完整的,并且会产生误导性的结果 。例如,在 JavaScript 中, null也被认为是object类型,更不用说其他几种极端情况了。请遵循以下建议,然后转到其他“最受好评(并且正确!)的答案”


原始答案

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

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

官方underscore.js使用此检查来找出某物是否真的是一个对象

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

更新

由于 V8 中存在先前的错误以及较小的微速度优化,因此更新的 underscore.js库现在正在使用以下内容。

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

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

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

有关此的更多信息以及为什么它是 typeof 的很好替代方法, 请查看本文

用于简单地检查对象或数组,而无需其他函数调用(速度)。就像也在这里张贴。

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() - 注意:仅用于对象文字,因为它对自定义对象(例如新的 Date 或新的 YourCustomObject)返回 false。

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

我很喜欢:

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

如果项目是 JS 对象,并且不是 JS 数组,并且也不为null … 如果所有三个都证明为 true,则返回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

使用Array.isArray函数:

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

没有函数Array.isArray

只是惊讶于有多少票赞成错误的答案😮
只有一个答案通过了我的测试!!!在这里,我创建了简化版本:

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等函数, isError可以考虑使用此通用函数的选项:

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 上创建了软件包 !它适用于所有先前描述的测试用例! 🙂

哦,我的上帝!我认为这可能比以往更短,让我们看看:

简短代码和最终代码

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

讲解

返回类型

JavaScript 对象的 typeof(包括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返回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/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility 中可能不起作用

好的,让我们在回答问题之前首先给您一个概念,在 JavaScript 函数中,对象是 Object,null,Object,Arrays 甚至 Date。因此,您看到没有像 typeof obj ==='object' 这样的简单方法,所以上面提到的所有内容都将返回 true ,但是有一些方法可以通过编写函数或使用 JavaScript 框架进行检查,确定:

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

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

纯 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);