2

So I'm working with WordPress and just spend an hour tracking down an issue between two plugins. They both use the same javascript variable 'd' but for different objects, so I had to change one of them to 'e', but those changes will be lost if the plugin ever updates.

There's thousands of plugins for WordPress, it's no surprise that programmers are using the same variables. Is there a way to prevent your own variables from being accidentally overwritten?

emc
  • 507
  • 1
  • 7
  • 25
  • All you have todo is to create a name space for your project. Check this [link](http://stackoverflow.com/questions/881515/javascript-namespace-declaration) – questborn Nov 21 '11 at 23:33
  • Basically, the "right" answer is a combination of dnuttle's and Caimen's: Whenever possible, avoid creating any global variables. If *necessary* (e.g, unrelated code needs to reach you, as in the library example), create at most one global variable, and put your various public features on that. – T.J. Crowder Nov 22 '11 at 00:04

2 Answers2

8

You can wrap your code with a function expression:

(function(){
    var e = 1;
}())

In the code above, nothing outside the function can touch your variables and your variables don't destroy other global variables of the same name.

Just remember that since your variables are not visible outside the function, all of your code that refers to them must also be inside it.

RobG
  • 142,382
  • 31
  • 172
  • 209
dnuttle
  • 3,810
  • 2
  • 19
  • 19
  • 1
    +1 AND it means that your variables can't stomp on any globals people have been foolish enough to create. Even if someone has created a global `e`, your code won't affect it. – T.J. Crowder Nov 21 '11 at 23:33
  • 1
    @BertEvans: It can be technicaly a closure if you return/export other inner functions that use the private variables. That said this particular pattern really is better described via the "module pattern" name instead of the generic "closure" – hugomg Nov 21 '11 at 23:36
  • 1
    @BertEvans - Technically it is, because every function forms a closure upon creation (see Myth 1 and Myth 4: http://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) – James Allardice Nov 21 '11 at 23:47
  • I could be way off base, but I still don't think it's a closure. The result of the immediately executing function is not stored in any variable so there is no scope left over to be "closed over." – Bert Nov 21 '11 at 23:53
  • @BertEvans et. al.: Yes, it is indeed a closure. **All** JS functions are closures. The fact it doesn't (in dnuttle's tiny example) refer to any of the data it closes over is irrelevant, it still closes over that data. Implementations are free to try to optimize that, but they have to be careful doing so (though if they don't see `eval` or `setTimeout` / `setInterval` with strings, it's easier). Details in [Section 10](http://es5.github.com/#x10-toc) of the spec. Moreover, though, code not shown is likely to refer to `window`, `document`, etc., which is only accessible because it's a closure. – T.J. Crowder Nov 21 '11 at 23:55
  • @BertEvans: *"The result of the immediately executing function is not stored in any variable so there is no scope left over to be "closed over."* Sorry, I didn't read that thoroughly the first time. Data within the function isn't the point, the function is a closure because it closes over the data in *its* surrounding context, not because something closes over the data in its context. If it created another function, that function would close over it (and all enclosing scopes), but that's a different thing. :-) – T.J. Crowder Nov 22 '11 at 00:00
  • `@dnuttle`: FWIW, I'd say the more common term in this case would be "scoping function," because while it is a closure, that's not the main point of what you're doing with it. The main point is you're creating a new scope so you can contain (and possibly shadow) variables. – T.J. Crowder Nov 22 '11 at 00:10
  • @T.J.Crowder - I think you are streching the meaning of closure too far. An authoritative definition of a closure is on the [comp.lang.javascript FAQ](http://www.jibbering.com/faq/notes/closures/). Note that `A closure is formed when one of those inner functions is made accessible outside of the function in which it was contained`. It isn't just the closed scope that creates a closure, it is when that scope is made available **outside** the function. – RobG Nov 22 '11 at 05:01
  • @dnuttle - that isn't the module pattern, it is an immediately invoked function expression (IIFE) - it has other names too. The module pattern uses closures to create a "module" of code, see [A JavaScript Module Pattern](http://www.yuiblog.com/blog/2007/06/12/module-pattern/). Incidentally, the pattern was developed by Richard Cornford and others at comp.lang.javascript and was popularised by Douglas Crockford in his articles on public and private members in javascript and work at Yahoo!. – RobG Nov 22 '11 at 05:04
1

The best practice is to use javascript namespaces.

var myApp = {}   
myApp.id = 0;
Caimen
  • 2,623
  • 2
  • 26
  • 43
  • No, the best practice is to avoid creating any global variables ***at all***. – T.J. Crowder Nov 21 '11 at 23:30
  • 3
    @T.J.Crowder - that's a pretty sweeping statement. If you are developing a library intended for use by other developers, and it doesn't plug into an existing global variable like `jQuery`, then you need to provide a global namespace for your API. There are perfectly valid reasons for creating a namespace at the global level – nrabinowitz Nov 21 '11 at 23:40
  • @T.J.Crowder That's certainly not true in every single case. Speaking in absolutes is never best practice. – Caimen Nov 21 '11 at 23:47
  • @nrabinowitz: I didn't say you could always avoid it, just that doing so is best practice. – T.J. Crowder Nov 21 '11 at 23:51
  • @Caimen: Indeed, nice one. :-) – T.J. Crowder Nov 21 '11 at 23:52
  • @T.J.Crowder - right, and I'm suggesting that it's best practice *only in certain situations.* – nrabinowitz Nov 22 '11 at 00:34