Let's say we have this code (forget about prototypes for a moment):
function A(){
var foo = 1;
this.method = function(){
return foo;
}
}
var a = new A();
is the inner function recompiled each time the function A is run? Or is it better (and why) to do it like this:
function method = function(){ return this.foo; }
function A(){
this.foo = 1;
this.method = method;
}
var a = new A();
Or are the javascript engines smart enough not to create a new 'method' function every time? Specifically Google's v8 and node.js.
Also, any general recommendations on when to use which technique are welcome. In my specific example, it really suits me to use the first example, but I know thath the outer function will be instantiated many times.
From what I understand, it is not so much a matter of "compiling" the function as it is having a different "scope" each time it is executed.
The second method you used will always have method
from the same scope.
The first method puts method
inside the scope of the A()
function call. So any information that is inside that scope (var foo
, function parameters, etc) are stored in that instance of the functions scope. So, the same function code will be referenced each time, but it will be in a different scope (and therefore a different "object").
Yes, you are creating a new Function object at each instantiation of an A object. You can demonstrate this as follows:
function A(){
var foo = 1;
this.method = function(){
return foo;
}
}
var a = new A();
var b = new A();
alert(a.method == b.method); // Returns false; two different Function objects
If you want to reuse the same Function object, make the method a property of the prototype, not the instances.
function B() {
this.foo = 1;
}
B.prototype.method = function() {
return this.foo;
}
var a = new B();
var b = new B();
alert(a.method == b.method); // Returns true; it's the same Function object
Edit: As far as I know, there is no reason to do something like the first version except to create private variables in a JavaScript object. In the original example, foo
is private. Nothing can access it directly from outside the object. Unfortunately, when you are instantiating a large number of objects using this technique, it can have an impact on performance and memory footprint.
In my code, I use a naming convention to distinguish between "public" and "private" properties. I name private properties with an underscore as the first character. So if I see something like myObject._someMethod()
, I know something is wrong.
Edit2: From http://code.google.com/apis/v8/design.html, I would think that V8 compiles the closure once, when it creates the hidden class which contains the method
property.
The method is not recompiled.
The Javascript interpreter will create a new closure object containing inner methods and local variables every time you call the outer methods.
The exact implementation depends on the Javascript engine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With