Unable to find real object constructor in JavaScript

I am seriously considering the ECMAScript 5.1 specification.

And I'm curious if there is a way to tell what the "real design function" of an object is in ES5. (not explicit property of "constructor")

According to the specification, the explicit property "constructor" is simply the initial backlink from the object of the side object of the function object to the function object.

(Here, a by-product is an object that is initially indicated by the explicit property "prototype" of the function object).

So, the explicit property of "constructor" has nothing to do with the real constructor of the object:

function Foo(name){ this.name = name; } var foo = new Foo("Brian"); var bar = { a: 10, b: function(){ if(this.name) return this.name; }}; Foo.prototype = bar; var foo2 = new Foo("John"); // Let me call Foo as "real constructor" of foo2 

Here, although foo2 was created by Foo, since Foo.prototype was pointing to bar at the time of foo2 creation, so foo2 internal [[Prototype]] points to bar, and we can check this for:

 Object.getPrototypeOf(foo2) === bar // true 

Since foo2 does not have its own “constructor” property, as usual, so reading foo2.constructor is actually a [[Prototype]] chain search, that is, foo2.constructor → ((foo2. [[Prototype]])). constructor -> bar.constructor, which is an Object, not a Foo.

You can check this out:

 foo2.constructor === Foo // false foo2.constructor === Object // true 

Finally, there is no way to find Foo from a foo2 object?

ADD: I'm talking about ES5. Please do not bring anything engine or ES6-thingy dependent (e.g. __proto__ )

+5
source share
1 answer

No, the language does not offer any function that does this.

If we turn to the specification of the new operator , we see that this is basically a call to the [[Construct]] function of the internal method. Turning our attention to [[Construct]] , we see:

When the internal [[Construct]] method for an object of function F is called with a possible empty list of arguments, the following steps are performed:

  • Let obj be the just created custom ECMAScript object.
  • Set all internal obj methods as described in 8.12.
  • Set the internal [[Class]] property of the obj object to " Object ".
  • Set the internal [[Extensible]] property of obj to true .
  • Let proto be the value of invoking the [[Get]] internal property of F with the argument < prototype ".
  • If Type (proto) is Object, set the internal [[Prototype]] property of obj for proto.
  • If Type (proto) is not an object, set the internal [[Prototype]] property of the obj object for the standard built-in object of the object prototype, as described in 15.2.4.
  • Let the result be called by the internal [[Call]] property of F, providing obj as that value and providing the argument list passed to [[Construct]] as arguments.
  • If Type (result) is Object, then returns the result.
  • Return obj.

As you can see in steps 5 through 7, the only processing of the object created with new is done by the environment to set it to [[Prototype]] , and then pass it to the [[Call]] method for processing in step 8. If the value assigned to the [[Prtototype]] object does not contain the exact constructor property, there is no way to find out which constructor function created the object.

You could, of course, save this information in your own constructor code by setting the value for the object at creation time, but the JavaScript engine will not do this for you.

+4
source

Source: https://habr.com/ru/post/1233184/


All Articles