If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Enjoy an ad free experience by logging in. Not a member yet? Register.

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.

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.

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.

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

Originally Posted by jmrker

What would be gained is the memory necessary for 99 extra versions of the method that performs the same task.

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'.

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.

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.

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.