sure. And you can check that something is a non-array non-function object all you like, but generally it’s easiest to just assume that if it’s an object, it can be used like one, without any “is plain object” check.
The difference from Array.isArray, is that check narrows down the type considerably. Knowing something is an object but not an array or function has not narrowed down the type by much, it could still be a Map, Set, ArrayBuffer or Object.create(null).
but it is better to be sure that this object is an object and not an array or anything else. I think people use Array.isArray, typeof v = = = 'string' and other type checking methods to make sure the code doesn't break. What is the object so deprived of?
I’m not sure what you mean. There’s typeof, and Array.isArray, and that’s basically it for a direct reliable test. (there’s indirect means, which https://npmjs.com/~inspect-js uses for all its “is-“ predicates.
previously, arr.indexOf (el)! = = -1 was used to verify the presence of an element in the array, but then arr.includes (el) was added and the code became much clearer. And I would like a more understandable code for checking an object for objects. You ask why check the type of variable on the object, but please watch how many times people on the Internet look for Check if a value is an object in JavaScript(Viewed 1.7m times)
The problem is that “object but not array” isn’t a type, it’s an arbitrary subset of a type. Typeof can be used to check for objects; arrays are objects.
If anything, Object.isObject should then be implemented using
typeof x == 'object' && x !== null || typeof x == 'function'
or using
Object(x) === x
So basically Object.isNotPrimitive. It shouldn't special-case any specific kind of object like array objects, function objects, primitive wrapper objects, regex objects, etc.
I could maybe see some value in a utility like this when it comes to JSON? What kinds of values result in {...} in JSON? Arrays don't. Functions don't. Just about any other object does. Dates don't, but they implement their own toJSON and, well, I don't think there's much you can do about that since you don't know what's coming out of that (for any arbitrary object that implements it) unless you call it.
There have also been times where I would have liked to know if an object was an ordinary object or not - something not exotic or with any hidden internal slots/methods that could cause unexpected behavior, irrespective of the prototype chain.
{} // yes
Object.create(null) // yes
Object.setPrototypeOf([], Object.prototype) // no (exotic array)
Object.setPrototypeOf(new String, Object.prototype) // no ([[StringData]] slot)
though I don't recall if there was any practical use for wanting this information or if it was more about curiosity. I suspect the latter.
...though the new String object above is also interesting for the JSON use case since stringify explicitly checks for primitive slots (like [[StringData]]) in objects for conversions. I guess they would also not be considered objects by that definition either.
That’s the problem - unfortunately, the way JS works is that (almost) everything inherits from Object (and null objects don’t inherit from anything). This means that answering the question “is this an object” doesn’t have an answer that’s simultaneously universal/generic, and also useful.
Each individual use case has to answer that themselves, and it wouldn’t make sense for the language to codify just one, or all, of those dozens of rubrics. Thus, things are indeed confusing here for newcomers, and that is both unavoidable and unfixable, due to the nature of the language.
Yeah, so perhaps here we need something a little more concrete than "is this an object", because what @bergus gave would be the canonical way to answer that.
However, this definition will include arrays and what-not, because those are objects, so it makes sense. If we don't include arrays, should we include TypedArray? If we don't include TypedArray should we include userland array classes? If we don't include userland array classes, well, how do avoid doing that?
Perhaps, what you're looking for is just a plain, simple object, the kind of object that you get with an object literal. If it's an instance of any class, you want Object.isObject() to return false. In other words, perhaps you want something like this:
We probably shouldn't call a function like this isObject(), since it's technically returning false for values that really are objects.
And, this will return false for objects that inherit from the null prototype, which is unfortunate. We could consider making a special case for that as well.
In 2011 there was a discussion about adding an Object.isObject method, harmony:typeof_null [ES Wiki], which which was primarily focused on fixing typeof null == 'object' semantics, but also should provide some useful context to this proposal thread.