Making Object Literals a sub-class of Object
2016-10-14 15:05 GMT+02:00 Brian Ninni <ninni.brian at gmail.com>:
I did a quick search and didn't find any recent mentions of this topic.
On more than one occasion I've had to determine whether something was a plain old Object, or some other class. This involves checking that the given object was NOT an instanceof any other acceptable class.
Does not ({}).toString.call(o);
work for that?
If you want to check that your variable is a plain old object and not some other class, you can use
Object.getPrototypeOf(x) === Object.prototype
Object.getPrototypeOf({}) === Object.prototype // true
Object.getPrototypeOf(new Map()) === Object.prototype // false
Le ven. 14 oct. 2016 à 15:05, Brian Ninni <ninni.brian at gmail.com> a écrit :
Brian Ninni wrote:
On more than one occasion I've had to determine whether something was a plain old Object, or some other class. This involves checking that the given object was NOT an instanceof any other acceptable class.
Object.prototype.isPrototypeOf(o)
should do that (if you don't care
about other realms).
Array, RegExp, Function, and Class Literals all already create an Object sub-class, so why not Object Literals?
Because Object-objects are just Objects and not anything special that would need a subclass with specific methods.
Are there any other major reasons why this is a bad idea?
As you already said, it would break a great lot of code.
I wrote:
Brian Ninni wrote:
On more than one occasion I've had to determine whether something was a plain old Object, or some other class. This involves checking that the given object was NOT an instanceof any other acceptable class.
Object.prototype.isPrototypeOf(o)
should do that (if you don't care about other realms).
Ooops, Object.getPrototypeOf(o) === Object.prototype
is what I meant.
({}).toString.call(o);
This does work for all Native class, but still returns "[object Object] " for user created classes
Object.getPrototypeOf({}) === Object.prototype // true
Did not know of that method. Seems like a roundabout way, but it works.
Object.prototype.isPrototypeOf(o)
Doesn't seem to differentiate between Literals and non-Literals.
Guylian's solution solves my main issue, so definitely not worth breaking a lot of code for.
I can see the possibility of someone wanting to extend the prototype for Object Literals only, and not all Objects, but that can also be accomplished by making a new class. So again, not a great reason for breaking code.
Thanks for the responses
Object literals (object initializers) are just a convenient way to create a new ordinary object which (initially) inherits from Object.prototype
, and populate it with some properties.
I don't think you should be able to distinguish them from similar objects not created using object initializers, e.g. new Object()
.
As already said, you can use Object.getPrototypeOf(obj) === Object.prototype
to check if obj
inherits from Object.prototype
.
But be aware that object literals can return object with a modified prototype:
var obj = {__proto__: Array.prototype};
Object.getPrototypeOf(obj) === Object.prototype; // false, but was created using object literal!
And the condition may hold for objects not created using object literals, e.g.
var obj = new Object();
Object.getPrototypeOf(obj) === Object.prototype; // true, but was not created using object literal!
Maybe you consider new Object()
to be an object literal, so the above would be OK.
But there can also be non-ordinary objects whose prototype is Object.prototype
:
var obj = Object.setPrototypeOf([], Object.prototype);
Object.getPrototypeOf(obj) === Object.prototype; // true, but it's an array!
Maybe what would be more interesting is having a way to check if an object is ordinary.
On Fri, Oct 14, 2016 at 9:05 AM Brian Ninni <ninni.brian at gmail.com> wrote:
I did a quick search and didn't find any recent mentions of this topic.
On more than one occasion I've had to determine whether something was a plain old Object, or some other class. This involves checking that the given object was NOT an instanceof any other acceptable class.
Array, RegExp, Function, and Class Literals all already create an Object sub-class, so why not Object Literals?
Terminology clarification: "Object literal" refers to the syntactic grammar definition.
It doesn't have to operate any differently than a standard Object does (though it allows room for deviation in the future), just have a different constructor so it can easily be determined whether it is a literal or not.
This would break code that uses
obj.constructor === Object
, but that code is not always reliable since the 'constructor' property can be overwritten without any side-effects anyway.Are there any other major reasons why this is a bad idea?
Objects created by new Object()
, Object()
, let/const/var o = {}
are
functionally equivalent*—changing the runtime semantics of only the
syntactic form would be a web-breaking change.
- Follow:
I did a quick search and didn't find any recent mentions of this topic.
On more than one occasion I've had to determine whether something was a plain old Object, or some other class. This involves checking that the given object was NOT an instanceof any other acceptable class.
Array, RegExp, Function, and Class Literals all already create an Object sub-class, so why not Object Literals?
It doesn't have to operate any differently than a standard Object does (though it allows room for deviation in the future), just have a different constructor so it can easily be determined whether it is a literal or not.
This would break code that uses
obj.constructor === Object
, but that code is not always reliable since the 'constructor' property can be overwritten without any side-effects anyway.Are there any other major reasons why this is a bad idea?