Making Object Literals a sub-class of Object

# Brian Ninni (8 years ago)

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?

# Petter Envall (8 years ago)

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?

# Guylian Cox (8 years ago)

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 :

# Bergi (8 years ago)

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.

# Bergi (8 years ago)

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.

# Brian Ninni (8 years ago)

({}).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

# Oriol Bugzilla (8 years ago)

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.

# Rick Waldron (8 years ago)

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:

tc39.github.io/ecma262/#sec