Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 11-04-2010, 10:43 PM   PM User | #1
johnmerlino
Regular Coder

 
Join Date: Oct 2009
Posts: 189
Thanks: 38
Thanked 3 Times in 3 Posts
johnmerlino is an unknown quantity at this point
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.
johnmerlino is offline   Reply With Quote
Old 11-04-2010, 10:58 PM   PM User | #2
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,178
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
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.
Old Pedant is offline   Reply With Quote
Old 11-05-2010, 03:36 AM   PM User | #3
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,454
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
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 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
rnd me is offline   Reply With Quote
Old 11-05-2010, 05:30 AM   PM User | #4
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,178
Thanks: 59
Thanked 3,995 Times in 3,964 Posts
Old Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to allOld Pedant is a name known to all
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.
Old Pedant is offline   Reply With Quote
Old 11-07-2010, 04:53 PM   PM User | #5
johnmerlino
Regular Coder

 
Join Date: Oct 2009
Posts: 189
Thanks: 38
Thanked 3 Times in 3 Posts
johnmerlino is an unknown quantity at this point
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.
johnmerlino is offline   Reply With Quote
Users who have thanked johnmerlino for this post:
TinyScript (11-07-2010)
Old 11-07-2010, 10:16 PM   PM User | #6
TinyScript
Regular Coder

 
Join Date: Mar 2009
Location: Portland Oregon
Posts: 690
Thanks: 44
Thanked 63 Times in 62 Posts
TinyScript is on a distinguished road
Great post. I have wondered why I should worry about it, but now I won't anymore.
TinyScript is offline   Reply With Quote
Reply

Bookmarks

Tags
classes, instance, javascript, prototype

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 10:51 PM.


Advertisement
Log in to turn off these ads.