6

I am trying for a while to switch constructor for a object and I am failing. Continuing code will show example of what I need. Thanks.

    <script type="text/javascript">

    function Me(){

      this.name = "Dejan";
    }

    function You(){

        this.name = "Ivan";
    }


    Me.prototype.constructor = You;
    somebody = new Me();


    alert(somebody.name); // **It gives Dejan, and I am expecting Ivan**

    </script>

4 Answers 4

14

The Me.prototype.constructor property is just a public property of Me.prototype, it is not used in any way in the construction of new objects or resolution of property names.

The only vague interest it has is that intially it references the function that its prototype "belongs" to and that instances of Me inherit it. Because it is a public property that can easily be assigned a new value or shadowed, it is not particularly reliable unless you have tight control over it and the code using it.

Sign up to request clarification or add additional context in comments.

4 Comments

it is not used in any way in the construction of new objects or resolution of property names. Actually it is used in resolving property names. That's why somebody.constructor === You. But you're right that it doesn't seem to be used in the construction of new objects. That appears to be a browser bug, and I propose a polyfill in my answer.
@personal_cloud—in the context of the OP, new Me() doesn't go to Me.prototype.constructor to create the instance, it calls Me directly. Nor does the Me.prototype.constructor object sit on the [[Prototype]] chain, so it's not used at all in resolving properties of instances (such as somebody.name).
If Me.prototype.constructor is not on the prototype chain, then how come assigning Me.prototype.constructor = You causes (new Me()).constructor == You?
The property is on the prototype chain, not the object it references.
5

You can't change the constructors of an object, you can however change the 'type' of the object the constructor returns, with (as in your example)

Me.prototype = new You();

which would cause new Me()'s to inherit from the object You. However this.name in the Me() function will overshadow the one inherited from you so do something like this:

function Me(){
    this.name =  this.name || "Dejan";
}
function You(){
    this.name = this.name || "Ivan";
}
Me.prototype = new You();
somebody = new Me();
alert(somebody.name); 

1 Comment

Output is "Ivan" to clarify for anyone who does not want to run
0

try:

Me.prototype = new You();

Me.prototype.constructor = You;
    somebody = new Me();


    alert(somebody.name); 

1 Comment

Didn't work for me in Chrome (prints "Dejan"). What's the theory for why this would work?
0

As RobG's answer explains, the browser is broken. Identifying the problem is a great first step. However, while "The browser is broken so fix your program" can solve the problem, "The browser is broken so fix the browser" is more logical. Here's one possible polyfill for new.

function NEW(clas, ...args)
{
  let res = Object.setPrototypeOf({}, clas.prototype);
  res.constructor.apply(res, args);
  return res;
}

This fixes the browser so you don't need to change your prototype. Only a minor change is required, to change new to NEW:

Me.prototype.constructor = You;
somebody = NEW(Me);
alert(somebody.name);

And this produces the desired result ("Ivan").

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.