Matty F
Matty F

Reputation: 3783

JavaScript closure vs. global variable

Which is best practice, which results in better performance?

UPDATE: jsperf.com reports that (a) is faster @ http://jsperf.com/closure-vs-global-variable

a) using a closure

var obj = {
    init: function() {
        var self = this;
        $('#element').click(function() {
            self.clickEvent();
        });
    },
    clickEvent: function() {
        this.miscMethod();
    },
    miscMethod: function() {}
};

b) using the global variable

var obj = {
    init: function() {
        // removed self=this closure
        $('#element').click(this.clickEvent); // simple method handler
    },
    clickEvent: function() {
        obj.miscMethod(); // global variable used
    },
    miscMethod: function() {}
};

Upvotes: 7

Views: 7574

Answers (5)

Claudiu
Claudiu

Reputation: 229361

The problem with your closure code is that it won't work in all cases. If you do:

obj.clickEvent()

then it'll work. But if you do:

var f = obj.clickEvent;
//hundreds of lines of code
f();

then it won't, as this will not refer to obj on that function call. If you just immediately pass obj off to something that doesn't use it in a strange way, though, then you won't have that problem, so it's 'cleaner'... but I still think it's too easy to make mistakes, so I recommend the global variable approach.

Upvotes: 1

subhaze
subhaze

Reputation: 8855

Nice write up about closures here.

JavaScript Closures - MDC

Upvotes: 0

JustcallmeDrago
JustcallmeDrago

Reputation: 1883

1) Since globals are dangerous, consider putting global variable names in all caps so that they're obvious to anyone (including you) who is reading the code.

2) your first snippet isn't valid.

function obj = {
     // your object stuff
}

should be

var obj = {
    // your object stuff
}

Additionaly, that's not actually a closure. Here is how you implement a singleton in Javascript.

var mySingleton = (function () {
    var privateVar = "foo";

    function privateFunction() { //this function can only be accessed by other private 
                                 //and privaleged functions defined in this closure
        // do stuff.
    }

    //stuff to run immediately that will also have access to private variables/functions

    singletonObj = {
         key1:"value1",
         key2:"value2",
         privilgedFunction: function () { // this method is accessible from the outside
             // do stuff. you can access private variables in here
         }
    };

    return singletonObj; //return the object that you just created
}()); //immediately execute the function, returning an object with private variables

I'm assigning the result of a function that I immediately execute to a variable. That function returns an object, therefore, I am assigning an object to that variable. BUT that object also has private members and private functions.

Upvotes: 0

PleaseStand
PleaseStand

Reputation: 32082

In most browsers, there is no significant performance difference; however, Chrome seems to suffer a 75% slowdown using this (correct my quick performance test if I am mistaken). Probably the main best practice issue is that it can sometimes be unclear which object this refers to.

As for declaring (or using without declaring) your own global variables, we call it global namespace "pollution" if we use too many of them. This can lead to different parts of JavaScript code interfering with one another, which good encapsulation using closures or "namespacing" avoids. The best practice is to only use at most one or two global variables. For example, jQuery uses just two: jQuery and $ (the latter can be turned off if it conflicts with another library).

Upvotes: 0

SLaks
SLaks

Reputation: 887453

Both should perform (almost) identically.

Best practice is to avoid globals.

Upvotes: 4

Related Questions