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.
// 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.
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.
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.
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.
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.
...
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
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%
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.
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.
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
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.
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%