constructor – [javascript]Why it works in its own space? – Code Utility


function Member(){
var test = new Member();
Member.prototype.x = "test";

I originally wrote like this for making a constructor expecting its output would be “test”. But it didn’t work, the result was “hello”.
But when I made the constructor to the below one, it worked.

function Member(){

I want to know how it was worked. Thanks.


When you perform new Member(), a couple of things happen, MDN described these steps quite nicely:

  1. Creates a blank, plain JavaScript object.

  2. Adds a property to the new object (__proto__) that links to the constructor function’s prototype object

  3. Binds the newly created object instance as the this context (i.e. all references to this in the constructor function now refer to the
    object created in the first step).

  4. Returns this if the function doesn’t return an object.

That means that in your examples:

  • test is the this object created in your Member constructor function when called with new (ie: the “instance”).
  • test‘s prototype (__proto__ property1) points to the object Member.prototype.

When you use test.x, we first look for x on the instance created by new Member() (ie: the this object that was created in your function and returned). If x cannot be found on the instance itself, then the prototype (object stored at the __proto__ property) is checked for x (and then if it can’t be found on the prototype we then check the prototype’s prototype and so on).

In your first example, since we’re able to find x on the object instance itself with the value of "hello" it logs "hello" and doesn’t check the prototype.

In your second example, since your function doesn’t add any properties to this, the instance returned by new Member() doesn’t have an x property like the first example did (its an empty object {}), and so we check the prototype (which from step 2 above we see is Member.prototype), which does have an x property set to "test", and so it logs "test". Performing Member.x adds x as a property to your function object, but doesn’t impact the instance created by using new.

1 Note that as RobG pointed out, the use of __proto__ is deprecated. The spec uses an internal slot, [[Prototype]], on the constructed object instance and is used to point to the constructor function’s .prototype property. Avoid using __proto__ and instead use methods such as Object.getPrototypeOf(), Object.create() or Object.setPrototypeOf() when you need to access / set the object for the [[Prototype]] slot (although, the use of setPrototypeOf() should still be used sparingly due to performance reasons)