Does encapsulating Javascript code in objects affect performance? - javascript

I am wondering if it is more or less efficient to encapsulate the main body of your JavaScript code in an object? This way the entire scope of your program would be separated from other scopes like window.
For example, if I had the following code in a JavaScript file:
/* My main code body. */
var somevar1=undefined;
var somevar2=undefined;
var somevarN=undefined;
function somefunction(){};
function initialize(){/* Initializes the program. */};
/* End main code body. */
I could instead encapsulate the main code body in an object:
/* Encapsulating object. */
var application={};
application.somevar1=undefined;
application.somevar2=undefined;
application.somevarN=undefined;
application.somefunction=function(){};
application.initialize=function(){/* Initializes the program. */};
My logic is that since JavaScript searches through all variables in a scope until the right one is found, keeping application specific functions and variables in their own scope would increase efficiency, especially if there were a lot of functions and variables.
My only concern is that this is bad practice or that maybe this would increase the lookup time of variables and functions inside the new "application" scope. If this is bad practice or completely useless, please let me know! Thank you!

I’ve no idea what the performance implications are (I suspect they’re negligible either way, but if you’re really concerned, test it), but it’s very common practice in JavaScript to keep chunks of code in their own scope, rather than having everything in the global scope.
The main benefit is reducing the risk of accidentally overwriting variables in the global scope, and making naming easier (i.e. you have window.application.initialize instead of e.g. window.initialize_application).
Instead of your implementation above, you can use self-calling functions to create an area of scope just for one bit of code. This is known as the module pattern.
This has the added advantage of allowing you to create “private” variables that are only accessible within the module, and so aren’t accessible from other code running in the same global object:
/* Encapsulating object. */
var application=( function () {
var someprivatevar = null// This can't be accessed by code running outside of this function
, someprivatefunction = function () { someprivatevar = someprivatevar || new Date(); };
return {
somevar1: undefined
, somevar2: undefined
, somevarN: undefined
, somefunction: function(){}
, getInitialized: function () { return someprivatevar; }
, initialize: function (){/* Initializes the program. */ someprivatefunction(); }
};
})();
application.initialize();
application.getInitialized();// Will always tell you when application was initialized

I realize you asked a yes or no question. However, my answer is don't worry about it, and to back that up, I want to post a quote from Eloquent Javascript, by Marijn Haverbeke.
The dilemma of speed versus elegance is an interesting one. You can
see it as a kind of continuum between human-friendliness and
machine-friendliness. Almost any program can be made faster by making
it bigger and more convoluted. The programmer must decide on an
appropriate balance....
The basic rule, which has been repeated by many programmers and with
which I wholeheartedly agree, is to not worry about efficiency until
you know for sure that the program is too slow. If it is, find out
which parts are taking up the most time, and start exchanging elegance
for efficiency in those parts.

Having easy to read code is key to my issue here, so I'm going to stick with the modular approach even if there is a slightly longer lookup chain for variables and functions. Either method seems to have pros and cons as it is.
On the one hand, you have the global scope which holds several variables from the start. If you put all of your code right in the global scope, your list of variables in that scope will include your own as well as variables like innerWidth and innerHeight. The list to search through when referencing variables will be longer, but I believe this is such a small amount of overhead it is ridiculous to worry about.
On the other hand, you can add just one object to the global scope which holds all of the variables you want to work with. From inside this scope, you can reference these variables easily and avoid searching through global variables like innerWidth and innerHeight. The con is that when accessing your encapsulated variables from the global scope you would have a longer lookup chain such as: globalscope.customscope.myvar instead of globalscope.myvar or just myvar.
When I look at it this way, it seems like a very trivial question. Perhaps the best way to go about it is to just encapsulate things that go together just for the sake of decluttering code and keep focus on readability rather than having a mess of unreadable code that is only slightly more efficient.

Related

Specific real life application of closures in javascript

I have used JS for two years and my pluralsight accessment rates me as proficient in JS, I understand prototypical inheritance, higher order functions, IIFEs etc and I have used them in real world instances but closures is one of those concept that you understand but can't find any reason why you would want to use them in real world development, I mean I know that if I say,
function expClosure(val){
//do something to val-->anotherVal
return function(val){return anotherVal)};
}
var exp = expClosure(val);
exp(); --> returns the value of anotherVal;
My question is why would I want to do this, or rather what specific instances can lead me to consider using this.
The main benefit to closures is you can "partially apply" a function using a closure, then pass the partially applied function around, instead of needing to pass the non-applied function, and any data you'll need to call it (very useful, in many scenarios).
Say you have a function f that will need in the future 2 pieces of data to operate. One approach is you could pass both pieces in as arguments when you call it. The problem with this approach is if the first piece of data is available immediately, and the second isn't, you'll have to pass it around with f so it's in scope when you want to call the function.
The other option is to give the available data to the function immediately. You can create a closure over the data, have the function reference the external data, then pass the function around by itself.
Option 2 is much simpler.
You can also use closures to implement static variables in functions in languages that don't natively support them. Clojure (the language) implements it's memoize function by having it return a modified version of the passed function that holds a reference to a map representing argument/return value pairs. Before the function is run, it first checks if the arguments already exist in the map. If they do, it returns the cached return value instead of recalculating it.
(Adapted from my answer to another question)
I wrote a bit about this in my practical bachelor thesis(2.2.2)
Hiding variables is a valuable usage of closure. Compared to some other languages variables can't be declared as private, public, etc. in JavaScript, but using closure you can hide variables that can only be used internally. E.g.
function Car() {
var speed = 0;
return {
accelerate: function() {
speed++;
}
}
}
var car = new Car();
car.accelerate();
speed is accessible by accelerate due to closure, but is otherwise completely inaccessible.
Since this question doesn't demand a programmatic answer, I am adding an answer and not a comment.
The example you quoted in the question is, I agree of a closure, and I am sure having access to pluralsight lectures, you well understand closures. So the aforestated example is not the only use case of closures. The closures are the functions which remember the scope in which they were created.
An obvious example of this is a callback registering mechanism which every one uses in jQuery. There are closures everywhere, and many of us have been unknowingly writing closures.
So if you have used redux, you would know the entire concept is based on closure, i.e. encapsulating the data(called state of application). Closure provisions a concept of private variables used in OOPS supporting languages.
I am adding another example of closure below, so you might be able to relate.
function processOrder(amount){
var temp_order_id = +new Date() + 'USERID';
var afterPaymentCompleteOrder = function(status){//callback
//afterPaymentCompleteOrder is a closure as it remembers the scope in which it is created when it is being called. So when ivoked it remembers the value of temp_order_id
if(status){
complete_order_method(temp_order_id);
}
else
delete_order_details(temp_order_id);
}
start_payment_process(amount, afterPaymentCompleteOrder);
}

Self executing functions with AngularJS

What are the benefits of using self executing functions with a framework, such as, Angular?
I am new to Angular but my understanding thus far is the module-based design gives most of the benefits that the Self executing function gives. What am I missing? Is it just a matter of style?
Here is an example by Ben Nadel. I really like the style but want to understand if there are any gains by writing Angular code this way or if it is mostly a style choice.
Mainly, it ensures that your code is not declared on the global scope, and any variables you declare remained scoped within your function.
In this case, it also has the benefit of declaring the objects required to run the code in one place. You can clearly see at the bottom that the angular and Demo objects are passed in, and nothing else. If the code was not wrapped in the function, you'd have to scan through the code to see what the dependencies were.
Personally, I prefer to use a module loader like RequireJS, which effectively forces you to follow this pattern.
That's kind of a opinion question. The main advantage I see on self executing functions is to not create global variables. I had never seen this pattern with angular.
On the example link you gave, it does not seem to have any advantage. The angular variable will exist anyway on a angular application, so you could use angular directly. And the Demo being a module, you can add controllers to it without without messing with the global scope.
I like a lot of self executing functions. But in this case I really don't see an advantage.
Daniel, you said: "if it is mostly a style choice".
I know at least two examples in javascript when "code style" is not only matter of preference but it causes different result.
Are semicolons optional? Not at all.
$scope.test = function() {
console.log('Weird behaviour!')
} //; let us comment it
(function() {} ()); //two functions seem to be independent
is equal to
$scope.test = function() {
console.log('Weird behaviour!')
}(function() {} ()); //but without semicolon they become the one
Another example of "code style" which is not related to self-executing functions:
var x = (function() {
return //returns undefined
{};
}());
alert(x);
/*
that is why, I suppose, while writing javascript code,
we put function brackets in the following "code style":
function() { //at the same line
return { //at the same line, this style will not lose the object
};
}
*/
Code style formation is dictated by unexpected results of such kind.
Last but not least.
With selfexecuting function: a closure is created on function call and keeps your vars local.
A closure is created on function call. That is why self-executing function is so convenient. As Daniel correctly mentioned it is a good place for keeping an independent code unit, this pattern is called module pattern. So when you move from pure javascript to specific framework or vise versa this independence enables code changes to be more fluid. The best case is just moving your module to an angular wrapper and reusing it.
So it is convenient for the purpose of code transmission from one technology to another. But, as I believe, it does not really make sence for specific framework.

Local Variables and GC

I'm trying to wrap my head around private variables in Javascript, temporary variables, and the GC. However, I can't quite figure out what would happen in the following situation:
MyClass = function() {
this.myProp = new createjs.Shape();
var tempVar = this.myProp.graphics;
tempVar.rect(0, 0, 10, 100);
tempVar = null;
var isDisposed = false;
this.dispose = function() {
if (isDisposed) return;
isDisposed = true;
}
}
var anInstance = new myClass();
My intention was to have isDisposed represent a private status variable, and tempVar be a use-and-throw variable.
Would tempVar get marked for GC? Would isDisposed be marked for GC too? How is the GC to know when I'm trying to declare a temporary variable meant for disposal, and when I'm trying to have a private variable within the object?
I tried to test the following in Chrome, and it seems as if tempVar never gets GC-ed as long as an instance of myClass exists. So I'm not sure what to believe now. I am incredulous that every single local variable that I create for temporary usage will exist in scope for the lifetime of the object.
Javascript does not have strongly typed objects. By setting tempVar to null, you're not declaring that you don't want to use it any more or marking it for collection as in Java or C#, you're merely assigning it a (perfectly valid) value. It's a trap to begin thinking that just because you made tempVar an "instance" of an object, that the variable is in fact an object and can be treated as such for its whole lifetime.
Basically, variables are just variables in Javascript. They can contain anything. It's like VB or VBScript in that regard. Scalars do undergo boxing in many cases (as in 'a|c'.split('|') making the string into a String) but for the most part, forget that. Functions are first-class objects meaning you can assign them to variables, return them from functions, pass them as parameters, and so on.
Now, to actually destroy something in Javascript, you either remove all references to it (as in the case of an object) or, in the case of an object's properties, you can remove them like this:
delete obj.propertyname;
// or //
delete obj[varContainingPropertyName];
To expand on that point, the following two code snippets achieve identical results:
function abc() {window.alert('blah');}
var abc = function() {window.alert('blah');}
Both create a local variable called abc that happens to be a function. The first one can be thought of as a shortcut for the second one.
However, according to this excellent article on deleting that you brought to my attention, you cannot delete local variables (including functions, which are really also local variables). There are exceptions (if the variable was created using eval, or it is in Global scope and you're not using IE <= 8, or you ARE using IE <= 8 and the variable was created in Global scope implicitly as in x = 1 which is technically a huge bug), so read the article for full details on delete, please.
Another key thing that may be of use to you is to know that in Javascript only functions have scope (and the window in browser implementations or whatever the global scope is in other implementations). Non-function objects and code blocks enclosed in { } do not have scope (and I say it this way since the prototype of Function is Object, so functions are objects too, but special ones). This means that, for example, considering the following code:
function doSomething(x) {
if (x > 0) {
var y = 1;
}
return y;
}
This will return 1 when executed with x > 0 because the scope of variable y is the function, not the block. So in fact it's wrong and misleading to put the var declaration in the block since it is in effect (though perhaps not true practice) hoisted to the function scope.
You should read up on closures in javascript (I cannot vouch for the quality of that link). Doing so will probably help. Any time a variable's function scope is maintained anywhere, then all the function's private variables are also. The best you can do is set them to undefined (which is more "nothing" than "null" is in Javascript) which will release any object references they have, but will not truly deallocate the variable to make it available for GC.
As for general GCing gotchas, be aware that if a function has a closure over a DOM element, and a DOM element somewhere also references that function, neither will be GCed until the page is unloaded or you break the circular reference. In some--or all?--versions of IE, such a circular reference will cause a memory leak and it will never be GCed until the browser is closed.
To try to answer your questions more directly:
tempVar will not be marked for GC until the function it is part of has all references released, because it is a local variable, and local variables in Javascript cannot be deleted.
isDisposed has the same qualities as tempVar.
There is no distinction in Javascript for "temporary variables meant for disposal". In newer versions of ECMAScript, there are actual getters and setters available, to define public (or private?) properties of a function.
A browser's console may provide you with misleading results, as discussed in the article on deleting with Firefox.
It's true, as incredible as it may be, that in Javascript, so long as a variable exists within a closure, that variable remains instantiated. This is not normally a problem, and I have not experienced browsers truly running out of memory due to tiny variables lying around un-garbage-collected. Set a variable to undefined when done with it, and be at ease--I sincerely doubt you will ever experience a problem. If you are concerned, then declare a local object var tmpObj = {tempVar: 'something'}; and when done with it you can issue a delete tmpObj.tempVar;. But in my opinion this will needlessly clutter your code.
Basically, my suggestion is to understand that in coming from other programming languages, you have preconceived notions about how a programming language ought to work. Some of those notions may have validity in terms of the ideal programming language. However, it is probably best if you relinquish those notions and just embrace, at least for now, how Javascript actually works. Until you are truly experienced enough to confidently violate the advice of those who have gone before you (such as I) then you're at greater risk of introducing harmful anti-patterns into your Javascript code than you are likely to be correcting any serious deficit in the language. Not having to Dispose() stuff could be really good news--it's this nasty pervasive task that Javascript simply doesn't require from you, so you can spend more time writing functionality and less time managing the lifetime of variables. Win!
I hope you take my words as kindly as they are meant. I don't by any means consider myself a Javascript expert--just that I have some experience and a solid competence in understanding how to use it and what the pitfalls are.
Thanks for listening!

What is this line at the top of some Greasemonkey scripts?

Background:
I have a self-taught hobbyist level of understanding of C++, which has translated into a similar understanding of javascript. As an attempt to understand javascript better, I decided to write a Greasemonkey script that would solve a problem with how Google handles multiple results from the same domain.
I wrote my script, and it was surprisingly easy. Now I feel like this script could be useful to others, so I'd like to release it. Before I do that though, I'd like to be certain I'm not releasing irresponsible code.
I know poor garbage collection is often cited as a problem with extensions, and did some research about what I would need to do in javascript to prevent that. It seems like the answer is any memory that is wrapped in a function will be reclaimed when that function exits. This seems to explain why a few popular scripts I looked at were wrapped in an otherwise useless function.
This leads me to these questions:
What should I do with my basic javascript function to ensure that it doesn't leak memory?
Is this, which I've seen in many scripts, an answer:
(function(){
//code goes here
})();
In the above code, what is the purpose of the first parentheses? It seems redundant to me.
While I was attempting to understand that line, I rewrote it as:
(function main(){
//code goes here
})
main();
The idea being that this was just calling the the previously unnamed function. This didn't work though, why?
I'm more interested in general answers, but in case it's needed here is my current code:
http://pastebin.com/qQWKfnJT
This pattern (wrapping a function in a pair of parenthesis and then placing another pair after the first pair) is called the " I mmediately I nvoked F unction E xpression" pattern (IIFE for short). What it does is define an anonymous function and then execute it immediately. The first set of parentheses mark the function as being an expression, rather than a statement. The second set execute the function returned from the first expression:
// This:
(function(){
// Todo: Add code
})();
// Translates *approximately* to this:
var _anonymous_function_2723113 = function() {
// Todo: Add code
};
_anonymous_function_2723113();
delete _anonymous_function_2723113;
As for why the function does not work when you give it a name, I would recommend reading up on kangaxx's article on the subject, especially where he touches on Named Function Expressions. The short of it is that when you have a named function expression (rather than a statement), the name is supposed to only be available to the function's scope.
So much for three and four - as for avoiding memory leaks, the IIFE is not a way to avoid memory leaks (as #elclanrs has pointed out, it merely helps you avoid polluting the global scope). To avoid memory leaks avoid circular references (and remember, closures can be a source of circular references).
Good luck, and enjoy yourself!
Here is an example, where anonymous functions can be used:
Lets have 4 elements with ids: id_1, id_2, id_3...
We want too loop over each of them and assign onclick event.
for (var i=0; i<5; i++) {
document.getElementById("id_"+i).onclick = function() {alert(i)}
}
When you click elements however each of them will alert the same - 4. The reason is that in the JavaScript closure only the last value is stored for local variables.
What you can do:
for (var i=0; i<5; i++) {
(function(n){
document.getElementById("id_"+n).onclick = function() {alert(n)};
})(i);
}
There are so many answers to this question in SO already... It's a self executing function. It's used in many cases to protect your code from the global scope. It's written in other ways too:
function(){}()
(function(){})()
(function(){}())
!function(){}()
(function(){}).call(this)

Is using with in javascript bad practise?

I'm thinking that stuff like with(Math){document.body.innerHTML= PI} wouldn't exactly be good practise.
I would call it bad practice, considering how it affects the scope chain.
Take a look at this article from Douglas Crockford: "with Statement Considered Harmful"
The short summary of the link in Matt's answer is that the problem with using the "with" statement is that the variables within the "with"'s block are ambiguous. Using the following example:
with(foo.doo.diddly.doo){
bar = 1;
baz = 1;
}
If you're not absolutely certain that foo.doo.diddly.doo has the bar or baz properties, you don't know if the bar and baz within the with statement are getting executed, or some global bar and baz. It's better to use variables:
var obj = foo.doo.diddly.doo;
obj.bar = 1;
obj.baz = 1;
In your example, though, Math is hardly a long enough term to justify even using a variable, but I'm guessing you have a more verbose application in mind than you've used for the question.
If you access (nested) object properties once, then there is no need "cache" them.
But if you access them more then once, then you should store a reference in a local variable. This has two advantages:
(nested) properties don't need to be lookup up more then once (potentially in the inheritance chain which is slow!).
Especially global objects (but any object that is not in the current scope) only needs to be looked up once in the scope chain. Subsequent access will be faster.
And now the connection to with:
It generates a new scope at beginning of the current scope chain. That means that any access to other variables/objects will cost at least one scope lookup more, even to variables that are local to the function.

Categories