Object.getConstructorOf();

# L2L 2L (11 years ago)

Object.getConstructorOf = function (obj){ return (((obj).constructor).toString().match(/\s\w+/)[0].trim()); }

Object.getConstructorOf(function(){});//function

/* there is no way to test for constructor via function. */

E-S4L N-S4L J

# L2L 2L (11 years ago)

I'll like to also proposal all method dealing with prototype as in getPrototypeOf, have a counterpart for constructor.

E-S4L N-S4L J

# L2L 2L (11 years ago)

I see the value of this, cause it denote not only the constructor, but what an object is:

Object.getConstructorOf("")//String Object.getConstructorOf(0)//Number Object.getConstructorOf(function(){})//Function Object.getConstructorOf({})//Object Object.getConstructorOf([]);//Array

If you try the fist to with Object.getPrototypeOf(""); Object.getPrototypeOf(0);

You'll get an error message, cause primitive value don't have prototype. But they do have wrapper objects; constructor objects.

This to me is a needed feature of the language.

E-S4L N-S4L J

# Brendan Eich (11 years ago)

L2L 2L wrote:

I see the value of this, cause it denote not only the constructor, but what an object is:

Object.getConstructorOf("")//String Object.getConstructorOf(0)//Number Object.getConstructorOf(function(){})//Function Object.getConstructorOf({})//Object Object.getConstructorOf([]);//Array

If you try the first to with Object.getPrototypeOf(""); Object.getPrototypeOf(0);

You'll get an error message, cause primitive value don't have prototype. But they do have wrapper objects; constructor objects.

This to me is a needed feature of the language.

It's not a "kernel language" feature, as you showed -- it is library code that can be built on top of the core language. And you are right that we seem to observe a fair amount of

Object.prototype.toString.call(x).slice(8, -1)

for value x.

However, getConstructorOf("") returning "String" (a string value), instead of the constructor function, is misleading. But returning the constructor function reference is wrong for primitive values, because 42 !== new (42).constructor(42). Primitives have value not reference semantics.

What you are really proposing is an Object.getToStringTag method. But in ES6, that is just x[Symbol.toStringTag], if I'm not mistaken. So do we really need Object.getToStringTag(x), which is longer?

See people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring for the ES6 spec.

Then you could argue that an Object "static method" is better both to hide the Symbol.toStringTag detail and to enable polyfilling on pre-ES6 browsers. That's a fair point.

# Andrea Giammarchi (11 years ago)

I see Object.getConstructorOf(x) rather a wrap of Object.getPrototypeOf(x).constructor where in a string version, which I agree with Brendan is kind of misleading anyway, would be Object.getPrototypeOf(x).constructor.name

Object.getConstructorOf = function (x) {
  return Object.getPrototypeOf(x).constructor.name || 'Object';
};

Now, how would this play with people still using anonymous expressions to create constructor is a mystery, since var A = function(){}; won't ever have a name so we are back to a more meaningful Object.getPrototypeOf(x).constructor instead of a string where again primitive will mostly fails since ambiguous 'cause indeed new String(123) !== String(123) but both have the same constructor.

This leads to the following approach:

Object.getConstructorOf = function (x) {
  return x instanceof Object ?
    Object.getPrototypeOf(x).constructor : null;
};

Now we have jut another problem, people still defining prototypes reassigning, instead of enriching, and forgetting the constructor:

function A() {}
A.prototype = {
  method: function () {
  }
};

Where is the constructor ? .... this trip to end up realizing that the constructor means actually nothing in JS world if not as generic implicit method from user land, and complete black box alchemy in native land.

Best

# Andrea Giammarchi (11 years ago)
  • generic implicit init method
# Rick Waldron (11 years ago)

On Sunday, September 21, 2014, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

I see Object.getConstructorOf(x) rather a wrap of Object.getPrototypeOf(x).constructor where in a string version, which I agree with Brendan is kind of misleading anyway, would be Object.getPrototypeOf(x).constructor.name

Object.getConstructorOf = function (x) {
  return Object.getPrototypeOf(x).constructor.name || 'Object';
};

Now, how would this play with people still using anonymous expressions to create constructor is a mystery, since var A = function(){}; won't ever have a name

This is not correct. Incidentally, there was discussion in the last hour on traceur about this, here is my response:

google/traceur-compiler#1365

Which cites: people.mozilla.org/~jorendorff/es6-draft.html#sec-variable-statement-runtime-semantics-evaluation

Look under VariableDeclaration : BindingIdentifier**Initializer, step 4.c.i

# L2L 2L (11 years ago)

L2L 2L wrote:

On Sep 21, 2014, at 2:57 PM, "Andrea Giammarchi" <andrea.giammarchi at gmail.com> wrote:

I see Object.getConstructorOf(x) rather a wrap of Object.getPrototypeOf(x).constructor where in a string version, which I agree with Brendan is kind of misleading anyway, would be Object.getPrototypeOf(x).constructor.name

Or more concise: ([]).constructor.name;//Array That's what I love about this language, meaning ways to go about programming... But that's changing, as APIs like function are being added into it...

I defer a little to this:

function *foo(){/yield/}

The yield sign which allow a yield--stop-- and continue if place in a loop inside a generator function... \be told me it couldn't be design as so:

generator foo(){ let x = 0; While(true){ yield x; x++; } }

The different is syntax style. But he said this too is not possible considering the conduction.

Many speculate that these are more so for libraries propose....

Back to the subject at hand:

With the Object.getConstructorOf([]); returns an function constructor: [function Array]

Here is a modify version:

Object.getConstructorOf = function (obj){ return (((obj).constructor)); }

Object.getConstructorOf.toString =
function(obj){ return "["+(((obj).constructor).toString().match(/^\w{8}\s\w+/)[0].trim())+"]"; }

Object.getConstructorOf([]); //function Array(){[native code]}

Object.getConstructorOf.toString([]); //[function Array]

Object.getConstructorOf([]).name; //Array

Object.getConstructorOf = function (x) {
  return Object.getPrototypeOf(x).constructor.name || 'Object';
};

Now, how would this play with people still using anonymous expressions to create constructor is a mystery, since var A = function(){}; won't ever have a name so we are back to a more meaningful Object.getPrototypeOf(x).constructor instead of a string where again primitive will mostly fails since ambiguous 'cause indeed new String(123) !== String(123) but both have the same constructor.

This leads to the following approach:

Object.getConstructorOf = function (x) {
  return x instanceof Object ?
    Object.getPrototypeOf(x).constructor : null;
};

Now we have jut another problem, people still defining prototypes reassigning, instead of enriching, and forgetting the constructor:

function A() {}
A.prototype = {
  method: function () {
  }
};

Where is the constructor ? .... this trip to end up realizing that the constructor means actually nothing in JS world if not as generic implicit method from user land, and complete black box alchemy in native land.

Best

On Sat, Sep 20, 2014 at 8:12 PM, Brendan Eich <brendan at mozilla.org> wrote: L2L 2L wrote:

I see the value of this, cause it denote not only the constructor, but what an object is:

Object.getConstructorOf("")//String Object.getConstructorOf(0)//Number Object.getConstructorOf(function(){})//Function Object.getConstructorOf({})//Object Object.getConstructorOf([]);//Array

If you try the first to with Object.getPrototypeOf(""); Object.getPrototypeOf(0);

You'll get an error message, cause primitive value don't have prototype. But they do have wrapper objects; constructor objects.

This to me is a needed feature of the language.

It's not a "kernel language" feature, as you showed -- it is library code that can be built on top of the core language. And you are right that we seem to observe a fair amount of

Object.prototype.toString.call(x).slice(8, -1)

for value x.

However, getConstructorOf("") returning "String" (a string value), instead of the constructor function, is misleading. But returning the constructor function reference is wrong for primitive values, because 42 !== new (42).constructor(42). Primitives have value not reference semantics.

What you are really proposing is an Object.getToStringTag method. But in ES6, that is just x[Symbol.toStringTag], if I'm not mistaken. So do we really need Object.getToStringTag(x), which is longer?

See people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring for the ES6 spec.

Then you could argue that an Object "static method" is better both to hide the Symbol.toStringTag detail and to enable polyfilling on pre-ES6 browsers. That's a fair point.

/be


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

E-S4L N-S4L J

# Andrea Giammarchi (11 years ago)

I honestly don't know if generators should show up as [function* name] or [generator name] when it comes to native, if there will ever be one, but you better leave toString as method name alone 'cause it's implicitly called any time you ('' + obj)... example:alert({toString:function(){return 123}})will alert"123"`

Not the best name for anything that is not supposed to do something else.

As you can see, troubles behind Object.getConstructor are many and there are already two results you expect or need for some reason, the good thing is that right now you have all tools (but Reflection) capable or giving you what you want/need/expect ... use them, but until you have a proper spec/proposal for such method I'd leave things are these are, which is less confusing for what we know so far about constructors and how we handle them.

Best