Get object's class name in ES5/ES5.1

111 Views Asked by At

In ES6 there is .constructor.name which can be used on any object to get its class name.

Is there something in ES5 that can do that?

(Note: Before commenters mention to upgrade the browser, etc., this question is about development for Fitbit, which uses JerryScript, a lightweight ES5.1-based engine)

TLDR of code that does not work:

class something {
  constructor() {
    console.log(this.constructor.name);
  }
}

new something();

It should normally output something, I guess, but it just says undefined.

2

There are 2 best solutions below

2
On

Section 13.2 of the ECMAScript 5.1 specification explains how all functions have a prototype property which itself has a constructor property.

A prototype property is automatically created for every function, to allow for the possibility that the function will be used as a constructor.

  1. Let proto be the result of creating a new object as would be constructed by the expression new Object() where Object is the standard built-in constructor with that name.
  2. Call the [[DefineOwnProperty]] internal method of proto with arguments "constructor", Property Descriptor {[[Value]]: F, { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}, and false.

So any object created with new someFunction should, by default, inherit the constructor property whose value is the someFunction function. The specification also specifies the constructor property of builtin object prototypes.

However, it does not mention the existence of a name property on constructors or functions. So if you want to specifically get the name of the constructor as a string, you would have to extract it from the representation returned by .toString() which is defined as such:

An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration. Note in particular that the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.

Alternatively, you can use Object.prototype.toString.call(obj) to produce a string which exposes the internal [[Class]] of a value, which is slightly different notion than the constructor property. Again, you'll have to extract the [[Class]] from the string yourself. Sadly, for custom functions, that just returns [object Object], so probably not what you're looking for.

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be the result of calling ToObject passing the this value as the argument.
  4. Let class be the value of the [[Class]] internal property of O.
  5. Return the String value that is the result of concatenating the three Strings "[object ", class, and "]".
0
On

ES5.1 function objects did not have a .name property. This was a widely-supported but non-standard extension that only got added to the spec with ES6.

CoreJs has a polyfill for it which relies on Function.prototype.toString(), which is supported in the latest JerryScript but may have to be enabled with the JERRY_FUNCTION_TO_STRING build option.