Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    Regular Coder
    Join Date
    Oct 2009
    Posts
    189
    Thanks
    38
    Thanked 3 Times in 3 Posts

    simulating classes in JavaScript

    Hey all,

    I am reading a book called JavaScript patterns. In it, this method is created:
    Code:
    var klass = function(Parent,template){
    	var Child, F, i;
    	
    	Child = function () {
    		if (Child.uber && Child.uber.hasOwnProperty("__construct")) {  
    			Child.uber.__construct.apply(this, arguments);
    		}
    		if (Child.prototype.hasOwnProperty("__construct")) {
    			Child.prototype.__construct.apply(this, arguments);
    		}
    	}
    	
    	Parent = Parent || Object;  
    	
    	F = function () {};
    	F.prototype = Parent.prototype;
    	Child.prototype = new F(); 
    	Child.uber = Parent.prototype;  
    	Child.prototype.constructor = Child;
    
    
    	for (i in template) {
    		if (template.hasOwnProperty(i)) {
    			Child.prototype[i] = template[i];
    		}
    	}
    	return Child;
    }
    Does anyone have an understanding of why we instantiate a new F() to the Child prototype rather than instantiate the Parent prototype? As you can see above, we assign Parent prototype to F prototype and then instantiate F() object to Child prototype. I'm not sure why it's being done this way.

    Code:
    	F.prototype = Parent.prototype;
    	Child.prototype = new F();
    Thanks for response.

  • #2
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,561
    Thanks
    80
    Thanked 4,492 Times in 4,456 Posts
    I would assume because you want a Closure.

    That is, you want to have an instance of the Parent.prototype in your Child without affecting the actual Parent.prototype.

    If you didn't do that, then Child would simply reference Parent, and all changes in Child would also be changes in Parent.

    But I've never seen this pattern, so that's a guess.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #3
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,400
    Thanks
    11
    Thanked 595 Times in 575 Posts
    Quote Originally Posted by Old Pedant View Post
    I would assume because you want a Closure.
    ...
    If you didn't do that, then Child would simply reference Parent, and all changes in Child would also be changes in Parent.

    It's more about inheritance chaining.

    It you didn't create a new blank object (using new) each time you ran klass(), you would only inherit from the last passed object's prototype.

    this way, you can keep tacking on more property collections.

    it's essentially an object property merge, though the props never merge; the just scoot down the chain...
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • #4
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,561
    Thanks
    80
    Thanked 4,492 Times in 4,456 Posts
    OH, silly me! I didn't even notice that klass() is a "factory"! Not creating a one-off class, used to create many.

    Yes! Makes lots of sense. But indeed, then, using a closure does this, no?
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #5
    Regular Coder
    Join Date
    Oct 2009
    Posts
    189
    Thanks
    38
    Thanked 3 Times in 3 Posts
    I'm not following this.

    The guy actually led up in the book to the klass design pattern, where the guy developed it piece by piece. In the book JavaScript Patterns, first he presents the problem:
    Code:
    function inherit(C, P) {
    C.prototype = P.prototype;
    }
    "This gives you short and fast prototype chain lookups because all objects actually share
    the same prototype. But that’s also a DRAWBACK because if one child or grandchild
    somewhere down the inheritance chain MODIFIES the prototype, it AFFECTS all parents
    and grandparents."
    However, I actually tried to modify the prototype say() in Child and it had no affect on Parent and in fact Child still pointed to Parent and completely ignored its own prototype of same name, which makes sense since it's pointing to a different memory position. So how can the guy says something like that? Below proves my point:
    Code:
    function Parent(){
    }
    
    Parent.prototype.say = function () {
    return 20;
    };
    
    function Child(){
    }
    
    Child.prototype.say = function () {
    return 10;
    };
    
    inherit(Child, Parent);
    
    function inherit(C, P) {
    C.prototype = P.prototype;
    } 
    
    var parent = new Parent();
    var child = new Child();
    
     
    var child2 = new Child()
    alert(child.say(); //20
    alert(parent.say()); //20
    alert(child2.say()); //20
    It's impossible for any child or grandchild to modify the prototype!

    This leads to my second point. He says the solution to the problem of the possibility of accidentially modifying parent prototypes down inheritance chain (which I can't reproduce) is to break the direct link between parent’s and child’s prototype while at the same time benefiting from the prototype chain. He offers the following as a solution:
    Code:
    function inherit(C, P) {
    var F = function () {};
    F.prototype = P.prototype;
    C.prototype = new F();
    }
    The problem is this outputs the same exact values as the other pattern:
    Code:
    function Parent(){
    }
    
    Parent.prototype.say = function () {
    return 20;
    };
    
    function Child(){
    }
    
    Child.prototype.say = function () {
    return 10;
    };
    
    inherit(Child, Parent);
    
    function inherit(C, P) {
    var F = function () {};
    F.prototype = P.prototype;
    C.prototype = new F();
    }
    
    var parent = new Parent();
    var child = new Child();
    
     
    var child2 = new Child()
    alert(child.say(); //20
    alert(parent.say()); //20
    alert(child2.say()); //20
    It doesn't make sense that an empty function somehow breaks a link. In fact, the Child points to F and F in turn points to the Parent's prototype. So they are ALL still pointing to the same memory position. This is demonstrated above, where it outputs the same exact values as the first example. I have no clue what this author is trying to demonstrate and why he makes claims that don't gel for me and that I can't reproduce.

    Thanks for response.

  • Users who have thanked johnmerlino for this post:

    TinyScript (11-07-2010)

  • #6
    Regular Coder
    Join Date
    Mar 2009
    Location
    Portland Oregon
    Posts
    690
    Thanks
    44
    Thanked 63 Times in 62 Posts
    Great post. I have wondered why I should worry about it, but now I won't anymore.


  •  

    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
    •