如何检查值是否是JavaScript中的对象?
当前回答
出于代码的目的,我找到了与上面的一些答案相对应的决定:
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
等等
其他回答
这很棘手,因为数组是对象类型,函数是对象类型而实际对象{}也是对象类型
问题
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
检查值类型的最合理方法似乎是typeof运算符。唯一的问题是它已经严重损坏:
它为null返回“object”,这属于null类型。它为属于Object类型的可调用对象返回“函数”。对于非标准的不可调用对象,它可以返回(几乎)它想要的任何内容。例如,IE似乎喜欢“未知”。唯一被禁止的结果是“函数”和原始类型。
typeof仅对非空基元可靠。因此,检查值是否为对象的一种方法是确保typeof返回的字符串与原语不对应,并且对象不为空。然而,问题是未来的标准可能会引入一种新的原始类型,我们的代码会将其视为一个对象。新类型并不经常出现,但例如ECMAScript 6引入了Symbol类型。
因此,我只推荐结果随值是否为对象而变化的方法,而不是typeof。以下是
测试值是否属于Object类型的正确方法的全面但不详尽的列表。
对象构造函数Object构造函数将传递的参数强制为对象。如果它已经是一个对象,则返回相同的对象。因此,您可以使用它将值强制转换为对象,并将该对象与原始值严格比较。以下函数需要ECMAScript 3,它引入了==:函数isObject(value){/*需要ECMAScript 3或更高版本*/return Object(value)==value;}我喜欢这种方法,因为它简单且自我描述,类似的检查也适用于布尔值、数字和字符串。但是,请注意,它依赖于全局对象,而不是隐藏或更改。施工人员实例化构造函数时,它可以返回一个不同于刚刚创建的实例的值。但该值将被忽略,除非它是一个对象。以下函数需要ECMAScript 3,它允许构造函数返回非对象。在抛出错误的ECMAScript 3之前,try语句当时不存在。函数isObject(value){/*需要ECMAScript 3或更高版本*/return new函数(){return value;}()==value;}虽然比上一个例子简单一点,但这个例子不依赖任何全局属性,因此可能是最安全的。此值旧的ECMAScript规范要求此值为对象。ECMAScript 3引入了Function.prototype.call,它允许调用具有任意此值的函数,但强制为对象。ECMAScript 5引入了一个严格模式,删除了这种行为,但在草率模式下,我们仍然可以(但可以说不应该)依赖它。函数isObject(value){/*需要ECMAScript 3或更高版本处于草率模式*/return函数(){return this==value;}.call(value);}[[原型]]所有普通对象都有一个名为[[Prototype]]的内部槽,其值决定它从哪个其他对象继承。该值只能是对象或null。因此,您可以尝试创建继承自所需值的对象,并检查其是否有效。Object.create和Object.getPrototypeOf都需要ECMAScript 5。函数isObject(value){/*需要ECMAScript 5或更高版本*/尝试{对象.create(value);返回值!==无效的}捕获(错误){return false;}}函数isObject(value){/*需要ECMAScript 5或更高版本*/函数构造函数(){}Constructor.prototype=值;return Object.getPrototypeOf(new Constructor())==值;}一些新的ECMAScript 6方式ECMAScript 6引入了一些新的间接方法来检查值是否为对象。他们使用前面看到的方法将值传递给一些需要对象的代码,该对象封装在try语句中以捕获错误。一些隐藏的例子,不值得评论函数isObject(value){/*需要ECMAScript 6或更高版本*/尝试{Object.setPrototypeOf({},值);返回值!==无效的}捕获(错误){return false;}}函数isObject(value){/*需要ECMAScript 6或更高版本*/尝试{新的WeakSet([value]);返回true;}捕获(错误){return false;}}
注意:我有意跳过了一些方法,例如Object.getPrototypeOf(value)(ES5)和Reflect方法(ES6),因为它们调用了可能会做坏事的基本内部方法,例如,如果value是代理。出于安全原因,我的示例仅引用值,而不直接访问它。
适用于所有数据类型。它只显示对象
if (data && typeof data === 'object' && !Array.isArray(data)) {
这取决于你所说的“是一个物体”。如果您想要所有非原语的内容,即可以设置新财产的内容,那么这应该可以做到:
function isAnyObject(value) {
return value != null && (typeof value === 'object' || typeof value === 'function');
}
它排除了基元(纯数字/NaN/Infinity、纯字符串、符号、true/false、undefined和null),但其他所有对象(包括Number、Boolean和String对象)都应返回true。注意,JS没有定义当与typeof一起使用时,应该返回哪些“主机”对象,例如窗口或控制台,因此很难用这样的检查来覆盖这些对象。
如果您想知道某个对象是“普通”对象,即它是作为文本{}创建的还是使用object.create(null)创建的,您可以这样做:
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;
}
}
编辑2018:因为Symbol.toStringTag现在允许自定义Object.protoct.toString.call(…)的输出,所以上面的isPlainObject函数在某些情况下可能会返回false,即使对象以文本形式开始其生命。可以说,按照惯例,带有自定义字符串标记的对象不再是纯对象,但这进一步模糊了Javascript中的纯对象定义。
哦,我的上帝!我认为这可能比以往任何时候都要短,让我们看看:
短代码和最终代码
函数isObject(obj){返回obj!=null&&obj.constructor.name==“对象”}console.log(isObject({}))//返回trueconsole.log(isObject([]))//返回falseconsole.log(isObject(null))//返回false
解释
退货类型
typeof JavaScript对象(包括null)返回“object”
console.log(类型为null,类型为[],类型为{})
检查其构造函数
检查其构造函数属性会返回带有其名称的函数。
console.log(({}).cconstructor)//返回名为“Object”的函数console.log(([]).cconstructor)//返回名为“Array”的函数console.log((null).cconstructor)//引发错误,因为null实际上没有属性
Function.name简介
Function.name返回函数的只读名称或闭包的“匿名”。
console.log(({}).cconstructor.name)//返回“Object”console.log(([]).cconstructor.name)//返回“Array”console.log((null).cconstructor.name)//引发错误,因为null实际上没有属性
注意:截至2018年,Function.name可能无法在IE中工作https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Browser_compatibility
推荐文章
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 我如何等待一个承诺完成之前返回一个函数的变量?
- 在JavaScript中根据键值查找和删除数组中的对象
- 使嵌套JavaScript对象平放/不平放的最快方法
- 如何以及为什么'a'['toUpperCase']()在JavaScript工作?
- 有Grunt生成index.html不同的设置
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格
- JavaScript: override alert()
- 重置setTimeout
- 如何确保<select>表单字段被禁用时提交?
- jQuery有不聚焦的方法吗?
- 反应钩子-正确的方式清除超时和间隔