www.webdeveloper.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23

Thread: Object literals and inheritance

  1. #1
    Join Date
    Mar 2011
    Posts
    19

    Object literals and inheritance

    Hi all, sorry for the newbie question. I really love the way Javascript objects inherit directly from other objects, rather than via a class structure. It seems lie a much more sensible way of doing things in an interpreted language. I have a small question though about something that seems to me like it should work but doesn't. If I define an object in an object literal like:

    var father = {
    i: "rudi",
    f: function() {
    alert(this.i)
    }
    }

    father.f();
    >> "rudi"

    I'm basically declaring an associative array or hash here containing 2 variables, one of which points to a string, and the other to a function I think. But if I do:

    var son = {
    prototype:father
    }

    son.f();

    I get an error. Surely the prototype is an variable with the object as it's scope. If so, why can I not set it directly in the object literal? It clearly doesn't work, but Id love to know why.

    Many thanks

  2. #2
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Oh. So you want to "clone" an object, right? I guess you may use a "vector" constructor for that, in order to separate the references. Something like:
    Code:
    <script type="text/javascript">
    function Clone(){}
    function clone(obj) {
        Clone.prototype = obj;
        return new Clone();
    }
    
    var father = {
    i: "rudi",
    f: function() {
    alert(this.i)
    }
    }
    var son=clone(father);
    son.f()
    </script>
    Now you have 2 independent objects, with the first object (father) delegating its prototype to the second one (son).

  3. #3
    Join Date
    Mar 2011
    Posts
    19
    Ah, this is where I come unstuck, I'm a Java/Ruby developer so do please bear with me. In Java, everything eventualy inherits from the Object class.

    My assumption was that, since I haven't explicitly set the prototype of father (it's a literal) it's prototype would be Object, which I assume is the base of the inheritance hierarchy tree.

    I assumed then that father.prototype would return a pointer to the base of the inheritance hierarchy. Is this way off base?

  4. #4
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    That happens, probably because prototype is a pre-built object, as being a fundamental property of all the objects. It can not be created ab-nihilo. It is a vector rather than a usual property, and it is created automatically when you create an object.
    When you write:
    Code:
    var son={
    prototype:father
    }
    You simply give the object a new custom property, called "prototype", but you don't delegate the prototype from an object to another Thus, if you need to check that, simply:
    Code:
    var father = {
    i: "rudi",
    f: function() {
    alert(this.i)
    }
    }
    var son={
    prototype:father
    }
    son.prototype.f()
    Last edited by Kor; 03-04-2011 at 09:33 AM.

  5. #5
    Join Date
    Mar 2011
    Posts
    19
    Ah yes, you're right. prototype is instantiated as a custom property. One thing still bothers me, and sorry again for the silly questions. What is the purpose of the new operator here? I would have thought that simply setting the prototype property would be sufficient to create an inheritance tree, but I see that it is not.
    Code:
    var father = {
      i: "rudi",
      f: function() {
        alert(this.i)
      }
    }
    
    var son = {
    }
    
    son.prototype = father;
    son.f();
    
    ==> son.f is not a function
    In Java, the new operator would create a new object with the specified class, and invoke it's constructor. In Javascript the object is already instantiated so doesn't need to be created, and I should be able to declare it's parent in the inheritance tree by setting the prototype operator (though I see that I can't). What does new do in this context?

    Many thanks, I really appreciate the time you're taking
    Last edited by goldfidget; 03-04-2011 at 11:41 AM.

  6. #6
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,503
    Quote Originally Posted by goldfidget View Post
    My assumption was that, since I haven't explicitly set the prototype of father (it's a literal) it's prototype would be Object, which I assume is the base of the inheritance hierarchy tree.

    I assumed then that father.prototype would return a pointer to the base of the inheritance hierarchy. Is this way off base?
    You're not off base. I think Kor merely misspoke. In his first example, the "son" object inherits from the "father" object, and the "father" object inherits from Object.prototype, exactly as you expected.
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  7. #7
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,503
    I think Crockford explains this topic better than anyone, and his videos may help.

    http://video.yahoo.com/watch/111585/1027823
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  8. #8
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,773

  9. #9
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Quote Originally Posted by Jeff Mott View Post
    You're not off base. I think Kor merely misspoke. In his first example, the "son" object inherits from the "father" object, and the "father" object inherits from Object.prototype, exactly as you expected.
    I did exactly what OP expected. I don't see where's the misspoke there. The OP wanted to create a new object which should inherit the prototype of another. So I did.

  10. #10
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,773
    The prototype object should be part of a Function object:
    Code:
    function Father(name) {
        this.name = name;
    }
    
    function Son() {}
    
    Son.prototype = new Father();
    Now "Father" is the parent of "Son". Prototypal inheritance in JavaScript is derived from the "__proto__" property in all objects.

    Given the code above:
    Code:
    var s = new Son();
    // s.__proto__ is Son.prototype
    // Son.prototype.__proto__ is Father.prototype
    // Father.prototype.__proto__ is Object.prototype
    // s.__proto__.__proto__.__proto__ is Object.prototype
    This "prototype chain" is set up by the browser whenever you use the "new" operator in conjunction with a constructor function, like Father or Son. When you declare an object literal, you are calling the Object constructor function, just with a different JavaScript syntax.

  11. #11
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,503
    Quote Originally Posted by Kor View Post
    I don't see where's the misspoke there.
    You said the "father" object delegates to the "son" object, but it's the other way around. The son delegates to the father, and the father delegates to Object.prototype.

    It's a seemingly small detail, but it caused some confusion.
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  12. #12
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Good analyze toicontien. But the bewilderment of the OP was related on the fact that he declared 2 objects in JSON (which would not have been a major impediment) but he tried to delegate the prototype property of one of them to the other one using JavaScript Object Notation. Which I think is not possible. That was all about.

  13. #13
    Join Date
    Dec 2003
    Location
    Bucharest, ROMANIA
    Posts
    15,428
    Quote Originally Posted by Jeff Mott View Post
    You said the "father" object delegates to the "son" object, but it's the other way around. The son delegates to the father, and the father delegates to Object.prototype.

    It's a seemingly small detail, but it caused some confusion.
    Ah, I see, you are right.Thanks for precise that.

  14. #14
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,503
    Quote Originally Posted by toicontien View Post
    Nice. That's a great resource and well worth a read. Though, I did want to caution against their method for achieving inheritance.

    Code:
    Son.prototype = new Father();
    This line, where we set up inheritance, has an unfortunate side-effect: it executes the Father constructor. What if, for example, the name property wasn't optional?

    Code:
    function Father(name) {
        if ( ! name) throw new Exception();
        this.name = name;
    }
    In this specific case, we could work around the issue by using a dummy name—"John Doe" perhaps—but in real-life scenarios, it may not be so easy. A constructor might manipulate the DOM or send an Ajax request, and we don't want all that to happen when we're only setting up inheritance. We need a way to create inheritance without executing the constructor.

    I think Douglas Crockford was the first to come up with this workaround:

    Code:
    function object(o) {
        function F() {}
        F.prototype = o;
        return new F;
    }
    What this function does is return a new, empty object that inherits from the given object. So now our inheritance setup would look like this:

    Code:
    Son.prototype = object(Father.prototype);
    Of course, there are still many ways to improve on this pattern. I like to re-package the object function into an "extend" method.

    Code:
    var BaseObj = {
        extend: function () {
            function F() {}
            F.prototype = this;
            return new F;
        }
    };
    
    var Father = BaseObj.extend();
    
    var Son = Father.extend();
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  15. #15
    Join Date
    Mar 2011
    Posts
    19
    Quote Originally Posted by Jeff Mott View Post
    You're not off base. I think Kor merely misspoke. In his first example, the "son" object inherits from the "father" object, and the "father" object inherits from Object.prototype, exactly as you expected.
    I thought that you could set the prototype object directly on any object, but I see from Crockford that you can only set it when calling a method as a constructor using the new keyword. To accomplish the above I would need to do:

    Code:
    var father = {
      i: "rudi",
      f: function() {
        alert(this.i)
      }
    }
    
    var son = Object(father)
    
    father.f();
    ==> rudi
    
    son.f();
    ==> rudi
    
    son.f = function() {
      alert("Rudi 2");
    }
    
    son.f();
    ==> Rudi 2
    Presumably the Object function is a calling a constructor function. It seems I can't use the object literal syntax right through, I have to break out into adding functions to classes.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

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



Recent Articles