SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Member
    Join Date
    Jan 2009
    Location
    In the hearts of people who passionately hate me
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    prototype chain confusion

    Hi all,

    Please take a look at the below code in JS.
    My Question:
    In the create function, the parent is copied by reference. A new object is created of "F" and returned. However, if I change the value of the "masterObject", it is reflected in "Object1" and "Object2" but not "object3".

    I don't understand why this is. Even when I think of prototype, I still don't get it. Please help me understand.

    Code JavaScript:
    function create(parent) {
      var F = function() {};
      F.prototype = parent;
      return new F();
    }
     
    var masterObject = {a: "masterObject value"}
     
    var object1 = create(masterObject);
    var object2 = create(masterObject);
    var object3 = create(masterObject);
    var object3.a = "overridden value";
     
    object1.a; // "masterObject value"
    object2.a; // "masterObject value"
    object3.a; // "overridden value"
     
    masterObject.a = "new masterObject value"
     
    object1.a; // "new masterObject value"
    object2.a; // "new masterObject value"
    object3.a; // "overridden value"

  2. #2
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,604
    Mentioned
    24 Post(s)
    Tagged
    1 Thread(s)
    You are getting object3.a and object3.prototype.a mixed up.

    The create copies the prototype. The prototype properties are only accessible without specifically referencing the prototype until such time as you attach a property with the same name directly to the object. Once you have defined object3.a you can no longer use that name to reference object3.prototype.a until such time as you delete object3.a

    If you were to delete object3.a and then try to reference it you will once again be accessing the prototype and will see the value that you updated in masterObject.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  3. #3
    SitePoint Member
    Join Date
    Jan 2009
    Location
    In the hearts of people who passionately hate me
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks that really helped.

    Hey, I can't help but ask the following question. Why can't I do this
    object3.prototype.a = "b" .... I want to use the object3 to change the value in the prototype. So, I would be changing the value of the "masterObject" via the object3.

    I'm just curious why I can't change the prototype value. It's only letting me override the property.

    Thanks again for the help

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,526
    Mentioned
    83 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by Adil K View Post
    I'm just curious why I can't change the prototype value. It's only letting me override the property.
    You can use __proto__ to go up the prototype chain, which allows you to get to the masterObject to make the change.

    Felgall may have a better understanding than me though on the details of why the standard prototype isn't able to be used in your situation.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,604
    Mentioned
    24 Post(s)
    Tagged
    1 Thread(s)
    The parent object is supposed to be a template from which you create objects using the create function. While you can modify the create function to allow changes to one object to be applied to all the other objects as well, you can't do it by changing that template object.

    The following allows you to change the property for all the child objects in one go by creating another property that points back at the template (provided of course that none of them have created a property with the same name as the prototype one):

    Code:
    function create(parent) {
      var F = function() {};
      F.prototype = parent;
      n = new F();
      n.uber = parent;
      return n;
    }
     
    var masterObject = {a: "masterObject value"}
    var object1 = create(masterObject);
    var object2 = create(masterObject);
    var object3 = create(masterObject);
    object3.uber.a = "overridden value";
    
    alert(object1.a); // "overridden value"
    alert(object2.a); // "overridden value"
    alert(object3.a); // "overridden value"
    I am not sure that I fully understand this myself but when you use either of those versions of create() the prototype for the object you assign it to us undefined. This variant creates your own replacement for it called uber (which is the German word for super without the umlaut - which was suggested by Douglas Crockford as an appropriate name to use for it since many other languages eg. Java refer to it by the name super which is unfortunately not available for this use in JavaScript).
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">


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
  •