Reputation: 3783
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
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
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
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
Reputation: 887453
Both should perform (almost) identically.
Best practice is to avoid globals.
Upvotes: 4