鉴于自从JavaScript
语言诞生以来的发展,为什么没有内置方法来检查一个对象是否是普通对象呢?
或者这个方法实际上存在吗?
鉴于自从JavaScript
语言诞生以来的发展,为什么没有内置方法来检查一个对象是否是普通对象呢?
或者这个方法实际上存在吗?
var a = new Date();
console.log(typeof a);
console.log(a instanceof Date);
var b = "Hello";
console.log(typeof b);
console.log(b instanceof Date);
根据OP的评论更新:
let arr = [1, 2, true, 4, {
"abc": 123
},
6, 7, {
"def": 456
},
9, [10], {}, "[object Object]"
];
arr.forEach(function(v) {
if (typeof v == "object" && !(v instanceof Array) && v != null)
console.log("Object Found");
else
; // console.log("Na");
});
instanceof
匹配数组,不仅仅是 {}
"[object Object]"
。 - guest271314JavaScript
方法来检查一个对象是否是 "[object Object]"
? - guest271314没有任何明确的直接方法可以检查一个值是否是对象,即属于Object类型,但有一些可靠的方法可以做到。我在另一个答案中写了一个列表,其中最简洁的方法似乎是
function isObject(value) {
return Object(value) === value;
}
类似的功能已经在esdiscuss上被多次提出请求。例如,
Juriy Zaytsev "kangax" 怀疑如何正确检查一个值是否为对象。
Object.isObject
被提出作为稻草人,并且它出现在ES6早期草案中。
TC39抨击:关于ES6草案中Object.isObject
的讨论。
Symbols有多原始?Bignums有多原始?等等:讨论了x === Object(x)
Object.isObject
稻草人最终被拒绝并从ES6草案中删除。
最近,
Object.isObject
现在有一个is{Type} Methods阶段0的提案,其中包括Object.isObject
和许多其他检查。
因此仍然有希望,最终我们可能会有这样的东西。
constructor
属性。但是任何对象都可以自定义它。Object.prototype.toString
来获取遗留的ES5 [[Class]]。但是任何对象都可以通过Symbol.toStringTag
自定义它。Object
可以作为标识符进行赋值。Object = 1; Object(1) === 1;
会抛出 Uncaught TypeError: Object is not a function
的错误,但 Object === 1 // true
是成立的。 - guest271314new function() { return value; }() === value
- OriolObject.is()
,Object.getPrototypeOf()
和Object.isPrototypeOf()
。当值为undefined
时,会抛出错误。虽然可以链式调用.map()
,但需要将值转换回原始值,这就需要额外的调用arr.map(Object).map(Object.getPrototypeOf).filter(Object.is.bind(null, Object.prototype))
。 - guest271314arr.filter(Object.is.bind(null, Object.prototype, Object.getProtototypeOf /* 将
arr 的当前元素传递给 Object.getProtototypeOf 然后调用 */))
,或类似的模式,而不是显式地使用function(element, index, thisArg){}
;只使用传递当前值的绑定函数引用。或者,确定是否无法实现该模式。 - guest271314[object Object]
字符串表示是不准确的。对于任何具有以下特征的对象,此行为可能会更改:let o = { toString: () => '...' };
('' + o) !== '[object Object]'
var a = [];
a.toString = () => '[object Object]';
('' + a) === '[object Object]';
let o = {}
Object.getPrototypeOf(o) === Object.prototype
constructor
属性没有被篡改,检查一个值是否为普通对象最简单的方法是:let o = {}
o.constructor === Object
Object
构造的POJO,不包括Object.create(null, { ... })
或任何子类(包括内置的如RegExp
或Array
):Object.create(null).constructor !== Object
[].constructor !== Object
(new class {}).constructor !== Object
{}
对象是不切实际的。在 JS 的上下文中,这几乎没有意义。这会阻止任何类实例或相对“纯粹”的对象(Object.create({}, ...)
)的使用。Object.assign({}, (new class {})).constructor === Object
o && typeof o === 'object' && !Array.isArray(o)
Array
、RegExp
等)的条件是:o && (o.constructor === Object || !/\[native code\]/.test(o.constructor))
"[object Object]"
(即普通对象)的方法呢?你能详细说明为什么检查"[object Object]"
不可靠吗?对于第一个例子我不太确定,可以再收集一下。 - guest271314{}
对象(根据上下文可能包括或不包括非 Object Object.create(null, { ... })
对象)。 - Estus FlaskObject.create
本身并没有什么特别之处。特殊情况是 Object.create(null)
(对象原型是 undefined
),Object.create({})
(对象原型是另一个对象)... 实际上,除了 Object.create(Object.prototype)
之外的任何情况都是如此。 - Estus Flask__proto__
是非标准化的。 ===
足够了,Object.is
在这里是多余的(它就是带有额外优势的 ===
)。 - Estus Flask只是为了进一步记录不同的方法:
我能想到的一种方式是:
JSON.stringify(testValue)[0] === '{';
每一个东西在 JavaScript 中都是一个对象,所以没有必要有一个 isObject API
undefined
和null
)。但它们绝对不是Object
对象。 - Estus Flask''.__proto__ === String.prototype && ''.constructor === String
。 - Estus Flask''
不是一个对象,但是当你引用一个属性时,JavaScript会将其转换为一个对象。虽然这似乎证明了字符串字面量是一个对象,但实际上并非如此。事实上,''.__proto__
被解析为 String('').__proto__
。我推荐你阅读《JavaScript原生类型的秘密生活》(The Secret Life of JavaScript Primitives),其中很好地解释了这一点。 - trincot
[] instanceof Object
匹配数组因为它们是对象并且原型继承自Object。如果您相对较新于JS,则可能需要一些时间来适应原型继承的概念。然后,o instanceof Object && Array.isArray(o)
应该很清楚(顺便说一句,它不涵盖Object.create(null)
)。 - Estus Flask