I have a value and want to know if it\'s an iteratable object literal, before I iterate it.
How do I do that?
If you use obj instanceof Object or typeof obj === "object" you get false positives on things like new Number(3) and arrays ([1,2,3]).
Using o.constructor === Object is great, however there's a weird edge case of Object.create(null) – which does, in fact, give you a plain object, albeit not one created in a "normal" way. Conceptually it gives a valid, normal, undecorated object. We check for this case with Object.getPrototypeOf(o) === null which will only hold true for the above undecorated object type.
The !!o converts null or undefined to false. People were complaining about it above, and honestly o && ... is more succinct and unless you're serializing it doesn't matter. Nevertheless, I included it.
function isObject(o) {
return o && o.constructor === Object
}
function isObject1(o) {
return !!o && o.constructor === Object
}
function isObject2(o) {
// edge case where you use Object.create(null) –– which gives an object {} with no prototype
return !!o && (Object.getPrototypeOf(o) === null || o.constructor === Object)
}