SitePoint Sponsor

User Tag List

Results 1 to 14 of 14
  1. #1
    SitePoint Enthusiast
    Join Date
    Jul 2008
    Location
    Wheaton, IL
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    What is the benefit/point of replacing an object's constructor property?

    I was recently perusing the source of a JavaScript library, and noticed some interesting code that I can't for the life of me figure out.

    I will not go into too much detail, but the following code should summarize well what I'm looking at:

    Code:
        var Something = function(options) {
            var obj = options.func;
            obj.constructor = Something;
            obj.prototype.constructor = obj;
            return obj;
        };
    
        var SomethingElse = new Something({
            func: function() {}
        });
    This is pretty easy to follow, but I don't see the point of replacing the object's constructor. It doesn't cause the returned object to inherit from the Something function, and
    Code:
    (SomethingElse instanceof Something)
    still returns false.

    Also, as I understand it, every new object's prototype property already has a constructor property that points to itself. So,
    Code:
    obj.prototype.constructor = obj
    just seems redundant.

    Am I completely missing something here?

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Perhaps this video that goes into depth about functions and inheritance will help:

    Crockford On JavaScript: Act III: Function the Ultimate (slides)

    The time segments that most closely relate to this are:
    50:24 Pseudoclassical Inheritance
    53:23 Prototypal Inheritance
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Enthusiast
    Join Date
    Jul 2008
    Location
    Wheaton, IL
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have actually seen those videos, and that particular video doesn't go into too much detail about the significance of the constructor property. And that is what confuses me. The constructor property seems completely useless, unless you are going to use it to tie that object to the assigned constructor function. However, this particular library does that nowhere.

    I guess my question is, in the example I gave earlier, why does it matter that SomethingElse's constructor property equals Something, and not just Function?

  4. #4
    SitePoint Member
    Join Date
    Sep 2010
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mwistrand View Post
    I have actually seen those videos, and that particular video doesn't go into too much detail about the significance of the constructor property. And that is what confuses me. The constructor property seems completely useless, unless you are going to use it to tie that object to the assigned constructor function. However, this particular library does that nowhere.

    I guess my question is, in the example I gave earlier, why does it matter that SomethingElse's constructor property equals Something, and not just Function?
    I feel Object constructor is a regular JS function and can be used for creating a object "type" and this object type can be used several times by avoiding in redefining the object every time for particular instance needs.

  5. #5
    SitePoint Addict
    Join Date
    Nov 2008
    Location
    Thailand
    Posts
    329
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    mwistrand, did you make any headway with this. I had a look myself, and it's a tad confusing.

  6. #6
    SitePoint Enthusiast
    Join Date
    Jul 2008
    Location
    Wheaton, IL
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by RLM2008 View Post
    mwistrand, did you make any headway with this. I had a look myself, and it's a tad confusing.
    Not really. I can understand replacing an object's constructor property if you want to create some sort of a link between two objects. However, the library I'm looking at doesn't make use of that functionality anywhere else.

  7. #7
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by mwistrand View Post
    Not really. I can understand replacing an object's constructor property if you want to create some sort of a link between two objects. However, the library I'm looking at doesn't make use of that functionality anywhere else.
    Here's what I get from the slides

    When using pseudoclassical inheritance there is no need to set prototype.constructor as that's already done for you. (slide 52)

    Setting the prototype.constructor is only needed when you are manually constructing a new object (slide 54)
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  8. #8
    SitePoint Addict
    Join Date
    Nov 2008
    Location
    Thailand
    Posts
    329
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    I watched the vid. Very good. Unfortunately got side tracked on #54 wanting to find out more about the ECMA 5 methods object.create and methods.keys. In fact I think it should be Object.keys(methods).

    As for needed, he did seem to imply that it was more optional, but it's still worth understanding why.

    Reading up on patterns and code re-use at the moment, but will come back to that or this

    RLM

  9. #9
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by RLM2008 View Post
    I watched the vid. Very good. Unfortunately got side tracked on #54 wanting to find out more about the ECMA 5 methods object.create and methods.keys. In fact I think it should be Object.keys(methods).

    As for needed, he did seem to imply that it was more optional, but it's still worth understanding why.
    It's not that it's optional, it's that when the object inherits from something other than Object, the constructor gets lost.

    Here's a partial transcript:

    This does the same thing as new, except that we don't use new.

    And then a little bit of extra plumbing - we don't really need to do this but just to be nice - we'll set the function's prototype property to the prototype because in the case of the hoozit, prototype got replaced and so we lost the constructor value, and we'll fix that there as well.
    Code javascript:
    var prototype = ...
    func.prototype = prototype;
    prototype.constructor = func;

    That's why the prototype.constructor assignment is required. When assign a different function as the prototype, the prototypes constructor winds up getting smashed, so you have to replace that constructor.

    That is not an issue with the OP code, but it's something to watch out for whenever you reassign the prototype method of an object.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  10. #10
    SitePoint Addict
    Join Date
    Nov 2008
    Location
    Thailand
    Posts
    329
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    Thanks for that. I tend to get the wrong end of the stick so forgive me for the following.

    Am I right in saying that the constructor property is key really to when you need to debug or run checks on instances?

    RLM

  11. #11
    SitePoint Enthusiast
    Join Date
    Jul 2008
    Location
    Wheaton, IL
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    When assign a different function as the prototype, the prototypes constructor winds up getting smashed, so you have to replace that constructor.

    That is not an issue with the OP code, but it's something to watch out for whenever you reassign the prototype method of an object.
    I apologize if I'm a little slow, but why does losing that constructor matter? The constructor property is not involved in inheritance, and in fact it doesn't seem to affect the code at all. It does look like a nice way to tie things up, but I'm trying to wrap my mind around what makes the constructor property so important when it doesn't really appear to do anything.

  12. #12
    SitePoint Addict
    Join Date
    Nov 2008
    Location
    Thailand
    Posts
    329
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    As I say mwistrand, I think it comes down to debugging and giving a clearer picture. If you're trying to figure out an issue and your instances are reporting the wrong constructor it could be confusing.

    Example

    Code:
    // no constructor set for child
    function inherit(child, parent){
    	var F =function(){}
    	F.prototype = parent.prototype;
    	child.prototype = new F();
    }
    Make our constructors, inherit, instance and log
    Code:
    function Parent(){} // Parent constructor
    Parent.prototype.method1 = function(){};
    
    function Child(){} // Child constructor
    
    inherit(Child, Parent);
    
    var newChild = new Child();
    
    console.log(newChild);
    Output in say Google Chrome
    Code:
    Parent
    __proto__: Parent
    __proto__: Parent
    constructor: function Parent(){}
    method1: function (){}
    __proto__: Object
    Change the method to set the constructor
    Code:
    function inherit(child, parent){
    	var F =function(){}
    	F.prototype = parent.prototype;
    	child.prototype = new F();
    	child.prototype.constructor = child; // reset constructor
    }
    Output this time
    Code:
    Child
    __proto__: Child
    constructor: function Child(){}
    __proto__: Parent
    constructor: function Parent(){}
    method1: function (){}
    __proto__: Object
    RLM

  13. #13
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by RLM2008 View Post
    As I say mwistrand, I think it comes down to debugging and giving a clearer picture. If you're trying to figure out an issue and your instances are reporting the wrong constructor it could be confusing
    That's one possible reason for it.

    Myself I believe that a better reason is that it helps to ensure consistency. Regardless of whether you use pseudoclassical inheritance or prototypal inheritance, the resulting object will be identical, which is how things should be.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  14. #14
    SitePoint Enthusiast
    Join Date
    Jul 2008
    Location
    Wheaton, IL
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks RLM2008 and pmw57. That makes sense. I just couldn't figure out if the constructor property did something I wasn't aware of.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •