7

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() {}
};
7
  • See my answer, and also this link: javascript.crockford.com/private.html It explains more on how closures work. Commented Nov 3, 2010 at 2:51
  • jsperf.com/closure-vs-global-variable/5 tells me that (b) is faster. What does that teach us about jsperf.com? Commented Nov 3, 2010 at 5:21
  • I don't know who created revision 5, but they've switched (a) and (b). So the Closures snippet is still faster. Commented Nov 3, 2010 at 5:50
  • “jsperf.com reports that (a) is faster” — good for them. As long as they recheck and republish their results every time one of the JavaScript engines is updated, and you remember to check it, then you’re on solid ground. Commented Nov 3, 2010 at 12:30
  • I guess by your logic we shouldn't be performance testing anything at all then. Cars, aeroplanes... ya know, in case something changes :-/ Commented Nov 4, 2010 at 4:50

5 Answers 5

4

Both should perform (almost) identically.

Best practice is to avoid globals.

Sign up to request clarification or add additional context in comments.

9 Comments

Thanks, can you elaborate? I thought declaring global variables was best avoided, hadn't heard that also applies to their use inside methods. Is there a reason for that?
+1 DOM methods provided by jQuery will by a huge margin overshadow any performance differences you might be able to detect in the two versions above.
@Hamish both a and b use jQuery, that wasn't the difference in question.
@Slaks I've read not to clutter the global object with your own variables, but I've never read that you should avoid using the global variables you've created where applicable. I guess what I'm getting at - is there a reason why b) is not considered best practice? cheers.
@Matty: He meant that the performance differences between types of variables will be negligible.
|
1

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.

1 Comment

It also won't work because clickEvent() doesn't return anything.
0

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

Comments

0

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.

2 Comments

It is a closure, a singleton pattern isn't required to form a closure. The execution context of the anonymous function in (a) is stored and has access to it's outer function variables (self)... ie. a closure.
Oh, I thought your "closure" was your function obj = {} thing!
0

Nice write up about closures here.

JavaScript Closures - MDC

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.