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 12-23-2012, 09:48 PM   PM User | #1
robin193
New to the CF scene

 
Join Date: Dec 2012
Posts: 3
Thanks: 1
Thanked 0 Times in 0 Posts
robin193 is an unknown quantity at this point
prototype question

Hi My name is Robin, I'm new at this forum and I am practicing javascript oop.
I'm getting stuck when it comes to prototype. I've read a lot about it but it is very hard to understand what prototype does.
I've made a little code from codeacedamy to explain my question.


function Cat(name, breed) {
this.name = name;
this.breed = breed;
// this.meow = function(){
// console.log("meoww!");
// };
}

// let's make some cats!
var cheshire = new Cat("Cheshire Cat", "British Shorthair");
var gary = new Cat("Gary", "Domestic Shorthair");

//Cat.prototype.meow = function(){
// console.log("meoww!");
//};

// add code here to make the cats meow!
cheshire.meow();
gary.meow();


My question: What is the difference between the two parts I placed in comments. I can let the cat "meoww!" just by giving the constructor this function, but I should do it on the prototype way. But I have no idea what the difference is.
I hope anyone can help my.

I'm sorry for my bad english.

Gr Robin

Last edited by robin193; 12-23-2012 at 09:50 PM..
robin193 is offline   Reply With Quote
Old 12-23-2012, 10:19 PM   PM User | #2
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,453
Thanks: 0
Thanked 498 Times in 490 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
The following creates a separate meow method for each and every object that you create from Cat. So if you define 100 cats then you will have 100 copies of the method.

Code:
this.meow = function(){
console.log("meoww!"); 
};
The following will create ONE copy of the meow method to share between all objects created from Cat - so that if you create 1000 cats you will still have only one copy of the method that is shared between all of them.

Code:
Cat.prototype.meow = function(){
console.log("meoww!");
};
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/
felgall is offline   Reply With Quote
Users who have thanked felgall for this post:
robin193 (12-23-2012)
Old 12-23-2012, 11:00 PM   PM User | #3
robin193
New to the CF scene

 
Join Date: Dec 2012
Posts: 3
Thanks: 1
Thanked 0 Times in 0 Posts
robin193 is an unknown quantity at this point
thanks for the fast reply,
so if I understand you correctly, on the prototype way the program is faster because the program has to execute the method once.
robin193 is offline   Reply With Quote
Old 12-24-2012, 02:09 AM   PM User | #4
jmrker
Senior Coder

 
jmrker's Avatar
 
Join Date: Aug 2006
Location: FL
Posts: 2,764
Thanks: 29
Thanked 453 Times in 447 Posts
jmrker will become famous soon enough
Arrow

Quote:
Originally Posted by robin193 View Post
thanks for the fast reply,
so if I understand you correctly, on the prototype way the program is faster because the program has to execute the method once.
I don't believe he said faster. The function will probably execute at a similar speed each time it is called.

What would be gained is the memory necessary for 99 extra versions of the method that performs the same task.
jmrker is offline   Reply With Quote
Old 12-24-2012, 08:19 PM   PM User | #5
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,203
Thanks: 59
Thanked 3,996 Times in 3,965 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 like to point out that you don't *HAVE* to use prototype to achieve the same memory savings.

You *can* code it as:
Code:
function Cat(name, breed) {
    this.name = name;
    this.breed = breed;
    this.meow = Meow;
};

function Meow()
{
    console.log("meoww!"); 
};
The advantage of using Cat.protoype.meow is that the function will be only available to Cat instances. In the code here, the Meow function could, for example, be called without reference to a Cat instance.
__________________
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 12-25-2012, 05:21 AM   PM User | #6
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,457
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
...
The advantage of using Cat.protoype.meow is that the function will be only available to Cat instances. In the code here, the Meow function could, for example, be called without reference to a Cat instance.
you can call prototype methods in the exact way: by name. It will NOT be
"only available to" anything. a name is a name, and call/apply/bind work on object paths the same as lexical entities.

[QUOTE=felgall;1301849]The following creates a separate meow method for each and every object that you create from Cat. So if you define 100 cats then you will have 100 copies of the method.

Code:
this.meow = function(){
console.log("meoww!"); 
};
that's not what the ecmaScript 3 spec says, i'll have to check 5. Functions are objects. Objects are passed byRef. this is determined at execution time. It's not safe to say that 100 distinct yet identical mallocs will result from the method...



Quote:
Originally Posted by jmrker View Post
What would be gained is the memory necessary for 99 extra versions of the method that performs the same task.

i don't see the memory savings, can you clarify what you mean?
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 12-25-2012 at 05:29 AM..
rnd me is online now   Reply With Quote
Old 12-25-2012, 06:53 AM   PM User | #7
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,203
Thanks: 59
Thanked 3,996 Times in 3,965 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
Quote:
Originally Posted by rnd me View Post
you can call prototype methods in the exact way: by name. It will NOT be
"only available to" anything. a name is a name, and call/apply/bind work on object paths the same as lexical entities.
Technically correct.

But look at the mess it takes to invoke a function defined via prototype in any other way.
Code:
function Cat( name, breed )
{
    this.name = name;
    this.breed = breed;
}
Cat.prototype.meow = function() { alert( this.name + " says meow" ); };

var f = new Cat( "Fred", "xx" );
f.meow();

var g = {
    name : "George",
    breed : "Manx"
};

Cat.prototype.meow.bind( g )( ); // ugly, isn't it?
************************

Quote:
i don't see the memory savings, can you clarify what you mean?
He was assuming the Felgall was correct about the extra 99 copies, of course.

You may well be correct that this doesn't occur. But I wouldn't be willing to bet that is true in, for example, MSIE 7 (to pick the obvious example).
__________________
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 12-25-2012, 08:58 PM   PM User | #8
felgall
Master Coder

 
felgall's Avatar
 
Join Date: Sep 2005
Location: Sydney, Australia
Posts: 5,453
Thanks: 0
Thanked 498 Times in 490 Posts
felgall is a jewel in the roughfelgall is a jewel in the roughfelgall is a jewel in the rough
Quote:
Originally Posted by rnd me View Post
Functions are objects. Objects are passed byRef. this is determined at execution time. It's not safe to say that 100 distinct yet identical mallocs will result from the method...
You overlooked the fact that new is being used to make the copies.

A simple way to prove that separate copies of the method exist for each object after creating them using 'new' would be to update the code in the original method. You will soon see that it does not update the copies of that method that have already been made using 'new'.

It is only when you don't use 'new' that objects are passed by reference.
__________________
Stephen
Learn Modern JavaScript - http://javascriptexample.net/
Helping others to solve their computer problem at http://www.felgall.com/
felgall is offline   Reply With Quote
Old 12-26-2012, 12:52 AM   PM User | #9
Logic Ali
Regular Coder

 
Logic Ali's Avatar
 
Join Date: Sep 2010
Location: London
Posts: 960
Thanks: 0
Thanked 198 Times in 193 Posts
Logic Ali will become famous soon enoughLogic Ali will become famous soon enough
Quote:
Originally Posted by felgall View Post

A simple way to prove that separate copies of the method exist for each object after creating them using 'new' would be to update the code in the original method. You will soon see that it does not update the copies of that method that have already been made using 'new'.
Code:
obj = function()
{
  this.func = function()
  {
   
  } 
}

alert( new obj().func === new obj().func ); // false


objP = function()
{
 
}

objP.prototype.func = function()
{
   
}

alert( new objP().func === new objP().func ); // true
Logic Ali is offline   Reply With Quote
Old 12-26-2012, 08:47 AM   PM User | #10
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,457
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 felgall View Post
A simple way to prove that separate copies of the method exist for each object after creating them using 'new' would be to update the code in the original method. You will soon see that it does not update the copies of that method that have already been made using 'new'.
the use of "new" has nothing to do with it. The JS engine generates internal function objects, and those objects get re-used. If two functions, even enclosed/anon functions, are the same code, the engine is allowed to substitute a pointer instead of a duplicate.




a simple test and chrome's task manager can shed some light on this:

in two different tabs, run the code below, and keep the focus off both tabs for at least 90 secs after execution to allow them to stabilize.

inlined
Code:
function Cat( name, breed ){
    this.name = name;
    this.breed = breed;
  this.meow = function() { alert( this.name + " says meow" ); };
}

var r=[];
for(var i=0, mx=999999;i<mx;i++){
 r.push(new Cat("kitty", "persian"))
}

setTimeout(function(){ document.title='inlined'; }, 2000 );

proto'd
Code:
function Cat( name, breed ){
    this.name = name;
    this.breed = breed;
}
Cat.prototype.meow = function() { alert( this.name + " says meow" ); };

var r=[];
for(var i=0, mx=999999;i<mx;i++){
 r.push(new Cat("kitty", "persian"))
}


setTimeout(function(){ document.title='protod'; }, 2000 );



results
since there were 1 million copies stored, fresh copies of the function object would have to cram into 238k or ~250,000bytes, 1/4 of a byte per method.

even on the total ram footprint, I only saw one byte more per object on the inline version:

Code:
tab	jsmem	js live
inline	7,060k	1,762k
proto  	6,080k	1,524k

one possibility that's compatible with the observation is that V8 uses an 8 bit pointer when the symbol count is low. that's just a guess, i'm not versed on implementation optimizations. either way, the results support what i've been saying all along: yes, in-lining might use a little more ram, but it won't use a linear scaling amount either.


If don't take my word, or the test's word for it, take the spec's!

from ECMAScript Language Specification Edition 3 (24-Mar-00) section 13.1.2 - Joined Objects
Quote:
Joined objects are used as a tool for precise specification technique in this standard. They are not meant to be used as a
guideline to how Function objects are implemented in practice. Rather, in practice an implementation may detect when the
differences in the [[Scope]] properties of two or more joined Function objects are not externally observable and in those cases
reuse the same Function object rather than making a set of joined Function objects. This is a legal optimisation because this
standard only specifies observable behaviour of ECMAScript programs.
Furthermore, section 13.2 explicitly mentions the exact case we've been discussing (in rather simple language) :
Quote:
Step 1 allows an implementation to optimise the common case of a function A that has a nested function B where B is not
dependent on A. In this case the implementation is allowed to reuse the same object for B instead of creating a new one every
time A is called. Step 13 makes this optimisation optional; an implementation that chooses not to implement it will go to step 2.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 12-26-2012 at 09:08 AM..
rnd me is online now   Reply With Quote
Old 12-26-2012, 09:23 AM   PM User | #11
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,457
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
Technically correct.

But look at the mess it takes to invoke a function defined via prototype in any other way.
Code:
function Cat( name, breed )
{
    this.name = name;
    this.breed = breed;
}
Cat.prototype.meow = function() { alert( this.name + " says meow" ); };

var f = new Cat( "Fred", "xx" );
f.meow();

var g = {
    name : "George",
    breed : "Manx"
};

Cat.prototype.meow.bind( g )( ); // ugly, isn't it?
if you do it like that, sure, but it need not be so brutal.


5 simple ways:

Code:
function Cat( name, breed ){
    this.name = name;
    this.breed = breed;
}

function unbind(method){return Date.call.bind(method); } // Library unbind function:
function purr() { alert( this.name + " purs loudly" ); };

var cp=Cat.prototype,
  g = {
    name :  "George",
    breed : "Manx" ,
    purr2:  purr
};

cp.meow = function() { alert( this.name + " says meow" ); };
cp.purr=purr;
cp.bark=Cat.bark=function() { alert ( this.name + "  can't bark, only dogs do that" ); };
var purr3=unbind(purr);


// not so ugly, is it?
purr3(g);
cp.meow.call( g );
purr.call( g );  
Cat.bark.apply( g );  
g.purr2( );
of course, i agree that writing out xxx.prototype.call every time is a PITA...
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 12-26-2012 at 09:33 AM..
rnd me is online now   Reply With Quote
Old 12-26-2012, 09:30 PM   PM User | #12
Old Pedant
Supreme Master coder!

 
Old Pedant's Avatar
 
Join Date: Feb 2009
Posts: 23,203
Thanks: 59
Thanked 3,996 Times in 3,965 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
LOL! No, it's not as ugly as my way. I'd say it's at least twice as ugly.

But never mind, I"ll concede the point that there are many ways to disenteguate a feline.
__________________
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 01-04-2013, 02:31 PM   PM User | #13
robin193
New to the CF scene

 
Join Date: Dec 2012
Posts: 3
Thanks: 1
Thanked 0 Times in 0 Posts
robin193 is an unknown quantity at this point
Now I understand it a bit.
Thank you all!
robin193 is offline   Reply With Quote
Reply

Bookmarks

Tags
oop, 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 09:42 PM.


Advertisement
Log in to turn off these ads.