Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  1. What should I do with my basic javascript function to ensure that it doesn't leak memory?
  2. Is this, which I've seen in many scripts, an answer:

    (function(){  
        //code goes here    
    })();
    
  3. In the above code, what is the purpose of the first parentheses? It seems redundant to me.

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

like image 807
DaleSwanson Avatar asked Aug 17 '12 01:08

DaleSwanson


1 Answers

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!

like image 59
Sean Vieira Avatar answered Oct 22 '22 03:10

Sean Vieira