I have a variable that is being set based on if it an object has a length as one of its properties. If not then I need to check if one of the properties exists. If so then get the first array stored in that object and return the length, else the variable is set to one. This could be combined all in statement like this.
var b=someObject;
var len = b.num||(b.arrs?(function(a){for(var x in a)return a[x].length})(b.arrs):false)||1;
The other way of doing this is pulling out the function and doing it like this
function getLength(a){for(var x in a)return a[x].length})
var b=someObject;
var len = b.num||(b.arrs?getLength(b.arrs):false)||1;
I was wondering if there is a performance penalty for doing it one way compared to the other? Is there a difference in how the javascript engine looks at them? The reason I would prefer the first way is it keeps me from having a bunch of extra helper functions.
The anonymous inline version is executed and discarded. Whereas the separate function instance is
a) Kept in memory and popped out with the rest of the local variables, if it is declared within a function
b) Kept in memory for the life time of the page if it is defined in global space as a member of the window object.
So if you are unlikely to need it again, it is best to go the anonymous inline route i believe.
Related
I'm studying THREE.js and noticed a pattern where functions are defined like so:
var foo = ( function () {
var bar = new Bar();
return function ( ) {
//actual logic using bar from above.
//return result;
};
}());
(Example see raycast method here).
The normal variation of such a method would look like this:
var foo = function () {
var bar = new Bar();
//actual logic.
//return result;
};
Comparing the first version to the normal variation, the first seems to differ in that:
It assigns the result of a self-executing function.
It defines a local variable within this function.
It returns the actual function containing logic that makes use of the local variable.
So the main difference is that in the first variation the bar is only assigned once, at initialization, while the second variation creates this temporary variable every time it is called.
My best guess on why this is used is that it limits the number of instances for bar (there will only be one) and thus saves memory management overhead.
My questions:
Is this assumption correct?
Is there a name for this pattern?
Why is this used?
Your assumptions are almost correct. Let's review those first.
It assigns the return of a self-executing function
This is called an Immediately-invoked function expression or IIFE
It defines a local variable within this function
This is the way of having private object fields in JavaScript as it does not provide the private keyword or functionality otherwise.
It returns the actual function containing logic that makes use of the local variable.
Again, the main point is that this local variable is private.
Is there a name for this pattern?
AFAIK you can call this pattern Module Pattern. Quoting:
The Module pattern encapsulates "privacy", state and organization using closures. It provides a way of wrapping a mix of public and private methods and variables, protecting pieces from leaking into the global scope and accidentally colliding with another developer's interface. With this pattern, only a public API is returned, keeping everything else within the closure private.
Comparing those two examples, my best guesses about why the first one is used are:
It is implementing the Singleton design pattern.
One can control the way an object of a specific type can be created using the first example. One close match with this point can be static factory methods as described in Effective Java.
It's efficient if you need the same object state every time.
But if you just need the vanilla object every time, then this pattern will probably not add any value.
It limits the object initialization costs and additionally ensures that all function invocations use the same object. This allows, for example, state to be stored in the object for future invocations to use.
While it's possible that it does limit memory usage, usually the GC will collect unused objects anyways, so this pattern is not likely to help much.
This pattern is a specific form of closure.
I'm not sure if this pattern has a more correct name, but this looks like a module to me, and the reason it is used is to both encapsulate and to maintain state.
The closure (identified by a function within a function) ensures that the inner function has access to the variables within the outer function.
In the example you gave, the inner function is returned (and assigned to foo) by executing the outer function which means tmpObject continues to live within the closure and multiple calls to the inner function foo() will operate on the same instance of tmpObject.
The key difference between your code and the Three.js code is that in the Three.js code the variable tmpObject is only initialised once, and then shared by every invocation of the returned function.
This would be useful for keeping some state between calls, similar to how static variables are used in C-like languages.
tmpObject is a private variable only visible to the inner function.
It changes the memory usage, but its not designed to save memory.
I'd like to contribute to this interesting thread by extending to the concept of the revealing module pattern, which ensures that all methods and variables are kept private until they are explicitly exposed.
In the latter case, the addition method would be called as Calculator.add();
In the example provided, the first snippet will use the same instance of tmpObject for every call to the function foo(), where as in the second snippet, tmpObject will be a new instance every time.
One reason the first snippet may have been used, is that the variable tmpObject can be shared between calls to foo(), without its value being leaked into the scope that foo() is declared in.
The non immediately executed function version of the first snippet would actually look like this:
var tmpObject = new Bar();
function foo(){
// Use tmpObject.
}
Note however that this version has tmpObject in the same scope as foo(), so it could be manipulated later.
A better way to achieve the same functionality would be to use a separate module:
Module 'foo.js':
var tmpObject = new Bar();
module.exports = function foo(){
// Use tmpObject.
};
Module 2:
var foo = require('./foo');
A comparison between the performance of an IEF and a named foo creator function: http://jsperf.com/ief-vs-named-function
To sum up the concept of scope chaining:
As soon as a web page is loaded, Javascript locates function definitions and creates a so-called Variable Object to each one.
Each VO has to reference each local variables (or global) and so start with the first ancestor's function until the global context.
Each function's scope chain is stored in the function property called: Scope.
Besides, when a function is called, a new object is created: an Activation Object.
What is this? :
It acts like a variable object(actually it is a VO) responsible for referencing all function internal's variable objects including the "arguments" object and formal parameters.
Of course, each of the chain composing of function ancestor's variable objects + function's Activation Object maps at least all variables to undefined firstly. Then, it evolves by updating its values (corresponding to referenced variables) as long as the execution progresses.
However, I notice Activation Object is different from a Variable Object solely because it contains the Arguments object and that this fact would prevent it to be created before function was called.
So, I wonder why people who built the Javascript engine didn't assign at the function's definition step each of the Activation Objects. Thus, when a function would be called, no need to create its own specific Activation Object since it already exists. Engine would just clear the corresponding arguments object at the end of the function execution so that the next call to this one could be possible without side effects.
Might it improve performance? Indeed, recreate a whole Activation Object at each call might consume.. Or is there an issue with this proposal?
Activation objects represent the context of a function invocation. Each invocation must have its own object. They are what allow for closures etc.
Think of it as being analogous to the stack frame allocated for a call to a C or C++ function.
edit — here's an example function:
function makeCounter( count ) {
return function() {
return count++;
};
}
Now, I can make a counter function with that:
var counter1 = makeCounter(1);
alert(counter1()); // alerts "1"
alert(counter1()); // alerts "2"
What if I make another one?
var counter100 = makeCounter(100);
alert(counter100()); // alerts "100"
If both calls to makeCounter() shared a single arguments instance, what would happen when I subsequently called "counter1()"?
You can't have a single Activation Object per function, reused across invocations, because there may be multiple invocations of a function in progress at any given time. One obvious example of this is recursion.
Perhaps you could have, say, 1 eagerly-allocated AO for each function, so at least the first call would be able to use it, but I imagine that kind of mechanism would just complicate the concept for, at best, a nominal performance gain (while also trading off memory).
So I have a rather large object orientated javascript class, with about 120 functions (a lot of getters and setters). Some of these functions have variables that are basically constants.
What I'm wondering, is should I declare these variables in a global scope of the object, so every time the function is run it doesn't have to re-declare the variable?
An example function is below. this.displayContacts is run several times (and will always run within the object), so in this case, there's no point declaring the 'codes' object inside the function?
function orderObject() {
this.displayContacts = function() {
var codes = {'02':'02','03':'03','07':'07','08':'08'};
// do something with codes
};
}
So, would this be better, performance wise?
function orderObject() {
var codes = {'02':'02','03':'03','07':'07','08':'08'};
this.displayContacts = function() {
// do something with codes.
};
}
My other concern is that if I end up with a lot of global variables/objects inside the main orderObject, will that be MORE of a performance hit than simply re-declaring the variables each time?
absolutely.
function MyClass() {
this.somevar = ''; // instance scoped variable
};
MyClass.CODES = {'02':'02'...}; // 'Class' scoped variable; one instance for all objects
MyClass.prototype.instanceMethod = function(){
// 'this' refers to the object *instance*
// it can still use MyClass.CODES, but can also account for variables local to the class
}
CONSTANT is 'static' so to speak, in java-talk. If your codes are global to the class (and the rest of your application), you will save a lot of overhead this way -- only define the object once. Note that you can have 'static' class-level methods as well, for those cases where the function doesn't need to operate on variables specific to an instance of the class.
Unless your app is really beefy, performance optimization probably wont make it noticeably faster. But that doesn't mean that OO design is not worth-while -- if you are going to use javascript in an object oriented way, its not too hard and never a bad idea to use good OO principals.
I would say that if you have something that you are using in multiple places that it should become a property of your object so that it doesn't have to be redeclared each time. It would also help make the maintenance of the object easier if that constant has to change. Then you are changing it only in one place and not having to hunt down all the locations where you used it.
Don't repeat yourself.
Garbage collection in JavaScript depends on the browser, and most modern browsers handle it pretty well. If you go ahead and make these global, you might see a slight performance increase simply because it's not executing that line of code every time. However, I can't imagine any significant increase in performance by making these static properties on the class, but if they don't change, then it would make more sense.
window.global_array = new Array();
window.example = function()
{
var x = new Object();
x['test_property'] = 3;
global_array.push(x);
}
Javascript gurus, please answer three questions:
will javascript delete x at the end of scope when example() returns, or preserve it inside global_array.
can I safely assume javascript works like 'everything is a reference' in python?
are all VMs created equal or will GC rules vary by implementation.
Yes. x will be deleted, because its scope is limited to the function body (you used the var keyword, which ensures this. Variables declared without var will be global, even when within a function body). However, the value x had will continue to be present in global_array.
Not entirely. Objects (arrays, too!) are passed as references, primitive values (like numbers) will be copied.
GC will vary by implementation, but this should be none of your concern. JavaScript implementations will behave the same, unless there is a bug.
Since x is referencing an object, the assignment (through push()) is increasing the reference count. When x going out of scope at the end of the function, this would not decrease the reference count to 0, so the object will still be there - its only reference now from within global_array.
My intuition is that it's a good idea to encapsulate blocks of code in anonymous functions like this:
(function() {
var aVar;
aVar.func = function() { alert('ronk'); };
aVar.mem = 5;
})();
Because I'm not going to need aVar again, so I assume that the garbage collector will then delete aVar when it goes out of scope. Is this right? Or are interpreters smart enough to see that I don't use the variable again and clean it up immediately? Are there any reasons such as style or readability that I should not use anonymous functions this way?
Also, if I name the function, like this:
var operations = function() {
var aVar;
aVar.func = function() { alert('ronk'); };
aVar.mem = 5;
};
operations();
does operations then necessarily stick around until it goes out of scope? Or can the interpreter immediately tell when it's no longer needed?
A Better Example
I'd also like to clarify that I'm not necessarily talking about global scope. Consider a block that looks like
(function() {
var date = new Date(); // I want to keep this around indefinitely
// And even thought date is private, it will be accessible via this HTML node
// to other scripts.
document.getElementById('someNode').date = date;
// This function is private
function someFunction() {
var someFuncMember;
}
// I can still call this because I named it. someFunction remains available.
// It has a someFuncMember that is instantiated whenever someFunction is
// called, but then goes out of scope and is deleted.
someFunction();
// This function is anonymous, and its members should go out of scope and be
// deleted
(function() {
var member;
})(); // member is immediately deleted
// ...and the function is also deleted, right? Because I never assigned it to a
// variable. So for performance, this is preferrable to the someFunction
// example as long as I don't need to call the code again.
})();
Are my assumptions and conclusions in there correct? Whenever I'm not going to reuse a block, I should not only encapsulate it in a function, but encapsulate it in an anonymous function so that the function has no references and is deleted after it's called, right?
You're right that sticking variables inside an anonymous function is a good practice to avoid cluttering up the global object.
To answer your latter two questions: It's completely impossible for the interpreter to know that an object won't be used again as long as there's a globally visible reference to it. For all the interpreter knows, you could eval some code that depends on window['aVar'] or window['operation'] at any moment.
Essentially, remember two things:
As long as an object is around, none of its slots will be magically freed without your say-so.
Variables declared in the global context are slots of the global object (window in client-side Javascript).
Combined, these mean that objects in global variables last for the lifetime of your script (unless the variable is reassigned). This is why we declare anonymous functions — the variables get a new context object that disappears as soon as the function finishes execution. In addition to the efficiency wins, it also reduces the chance of name collisions.
Your second example (with the inner anonymous function) might be a little overzealous, though. I wouldn't worry about "helping the garbage collector" there — GC probably isn't going to run in the middle that function anyway. Worry about things that will be kept around persistently, not just slightly longer than they otherwise would be. These self-executing anonymous functions are basically modules of code that naturally belong together, so a good guide is to think about whether that describes what you're doing.
There are reasons to use anonymous functions inside anonymous functions, though. For example, in this case:
(function () {
var bfa = new Array(24 * 1024*1024);
var calculation = calculationFor(bfa);
$('.resultShowButton').click( function () {
var text = "Result is " + eval(calculation);
alert(text);
} );
})();
This results in that gigantic array being captured by the click callback so that it never goes away. You could avoid this by quarantining the array inside its own function.
Anything that you add to the global scope will stay there until the page is unloaded (unless you specifically remove it).
It's generally a good idea to put variables and function that belong together either in a local scope or in an object, so that they add as little as possible to the global namespace. That way it's a lot easier to reuse code, as you can combine different scripts in a page with minimal risks for naming collisions.