2

I was reading this JavaScript code.

What I don't understand, is why the author does this:

(function(namespace) {
    //more stuff here
    namespace.Game = Game;
})(window);

What is the purpose of namespace.Game = Game; instead of window.Game = Game;?

Does it make the Game function reusable?

John Slegers
  • 45,213
  • 22
  • 199
  • 169
Haris Z
  • 119
  • 1
  • 7
  • duplicate: http://stackoverflow.com/questions/8228281/what-is-the-function-construct-in-javascript – ste2425 May 19 '16 at 09:08
  • @ste2425 : One of the OP's comments : `I'm not confused with IIFE, just that why he assign Game to namespace.Game instead of just window.Game`. Judging by that comment, I'd argue that this question doesn't qualify as a duplicate. Anyway, I added the question to remove the ambiguity, as several other people seem to have interpreted it as a request for an explanation of what's the point of using IFEE... – John Slegers May 19 '16 at 10:38

5 Answers5

4

Looks like author is from C++ community :P, so he used the variable name "namespace" !!!

Author of this created the IIFE (Immediately Invoked Function Expression) so he/she can create private/isolated scope, he is passing global window object as parameter for enhancing performance by reduce the scope lookup time.(Remember Javascript looks for property in local scope and way up chaining till global scope). So accessing window object at local scope reduce the lookup time. Then he/she updated the global object with property "Game".

Gurucharan M K
  • 879
  • 1
  • 9
  • 7
1

Author creating the IIFE (Immediately Invoked Function Expression) and passing window object as an argument, so the current function expression has it's own isolated scope, still taking explicit control to accessing global variables

markoffden
  • 1,406
  • 1
  • 15
  • 31
  • I'm not confused with IIFE, just that why he assign Game to namespace.Game instead of just window.Game – Haris Z May 19 '16 at 09:17
  • Well, Kyle Simpson in his You Don't Know JS: Scope and Closures explains it like "so that we have a clear stylistic delineation for global versus nonglobal references". Why not using window.Game directly? Hmmm... Cause this is not a common practice and far more it's always better to have your own variables set in the block of moduled code – markoffden May 19 '16 at 09:24
1

I will refer to Game as foo in the text below.

By doing so foo will be accessible trough the global window, like window.foo. However, the decision on where to share foo should not come from the same person that wrote foo, but rather from the person that integrates foo in his code. This is just a best practice for improved interoperability/reusability.

If you don't do this, foo won't be visible to anyone outside the IIFE.

If you assign foo to window directly, the other implementation party would have to modify your code instead of changing a single argument. It is all about what kind of knowledge do you really need inside your code. Do you really want to know about where foo will be shared, or do you just want to share it somewhere?

Also, if you simply access window from within your IIFE you are accessing a global variable. Please read here - "don't pollute global namespace".

Community
  • 1
  • 1
M K
  • 9,138
  • 7
  • 43
  • 44
0

To understand the point of IFEE, see What is the (function() { } )() construct in JavaScript?. Basically, it's all about avoiding global variables as much as possible.

So what about the use of the namespace parameter in this context? Well, the value of namespace is the window object, because the window object is passed to the self-executing anonymous function that encapsulates your code as the namespace parameter. So, namespace.Game = window.Game.

One reason for using a namespace parameter and not just the window object directly, is because namespace can be minified, while window cannot... which means you can save a lot of bytes if you need to reference the window object a lot.

Another reason for using a namespace variable, is because you might want your code to be compatible with other environments where the window object doesn't exist (like NodeJS) at some later time. Or, you might want your code to be rewritten as eg. a RequireJS module. Not hardcoding the window object anywhere except the anonymous function wrapped around your code makes that a lot easier.

Or maybe you just want to change the scope as some later point in time? Maybe you want to add your Game to a different object at some later point in time? This too would be a lot easier if you avoid hardcoding the window object anywhere except the anonymous function wrapped around your code.

John Slegers
  • 45,213
  • 22
  • 199
  • 169
  • it is like add a property to windows object? what do u mean by minified? what's wrong with doing window.Game? same thing for me. – Haris Z May 19 '16 at 09:09
  • @Haris Z : There's nothing wrong with using `window.Game` directly. It's just more efficient to assign it to a variable as in the code example you mentioned. Anyway, I added some more info. I hope that helps? – John Slegers May 19 '16 at 09:12
  • @JohnSlegers saying that this technique is used for `minification` benefit is like saying that we use cars because they look nice. – M K May 19 '16 at 09:15
  • @M K : Better minification is the main reason I'm using this technique in frontend only code. If you don't think that's a valid reason, please elaborate! – John Slegers May 19 '16 at 09:17
  • @JohnSlegers It's all about avoiding usage of global variables and limitation of knowledge. – M K May 19 '16 at 09:23
  • @MK : How exactly does this technique avoid usage of global variables? All it does is just substitute `window.Game` with `namespace.Game`, where `namespace` is a reference to the `window` object. – John Slegers May 19 '16 at 09:27
  • @HarisZ : Judging by MK's comments, the downvoters don't really seem to understand themselves what's the point of using this technique. Anyway, I added some additional reasons for using it! – John Slegers May 19 '16 at 09:28
  • @JohnSlegers You pass in a reference. It is a reference to a global variable, but it can be changed to anything else anytime. – M K May 19 '16 at 09:29
  • @MK : True. While I do consider improved minification to be the main benefit of this technique (it's the main reason I use it in my own code), making it easier to alter the scope at a later point in time definitely is another benefit... which I mentioned in the paragraphs I just added. – John Slegers May 19 '16 at 09:31
  • @JohnSlegers It's either we don't understand you, or you don't understand us, isn't it? – M K May 19 '16 at 09:36
  • @MK : ... or both ;-) Anyway, have you seen the latest update of my answer? I do believe that - besides not mentioning the term `IIFE` - it is rather complete now. If you don't agree, feel free to point out what you still consider missing. – John Slegers May 19 '16 at 09:39
  • @MK it avoids globals because any variables declared within it will not be implicit globals but only declared within its scope. With `strict mode` that is a moot point now. Obviously any deps 'injected' in (i used injected loosely) if they are already global then it makes no difference either. – ste2425 May 19 '16 at 10:11
  • @ste2425 : I'm aware of that. However, that's not what the author of this question is after. As he explains in the comments, he wants to know why the `namespace` parameter is used instead of just referencing `windows` directly. I just realized that his question could be interpreted differently, though (which also explains the downvotes I got), so I edited it for the sake of clarification. – John Slegers May 19 '16 at 10:24
  • @ste2425 : One of his comments : `I'm not confused with IIFE, just that why he assign Game to namespace.Game instead of just window.Game` – John Slegers May 19 '16 at 10:24
  • @HarisZ : I just realized why I received two downvotes. Many people seem to interpret your question differently, thinking you want to know what's the point of using IFEE. As that's obviously NOT what you're looking for based on your comments, I edited the question to remove the ambiguity. – John Slegers May 19 '16 at 10:29
  • 1
    @JohnSlegers i was responding to your comment `How exactly does this technique avoid usage of global variables? All it does is just substitute window.Game with namespace.Game, where namespace is a reference to the window object.` However i realize now you meant the consumption of globals not the pollution, leaking/creating of globals. – ste2425 May 19 '16 at 10:35
0

This expression is called IIFE( immediately-invoked function expression ). The main usage is to create a 'scope'. Since only functions create scope in javascript. When you want to hide your values from global environment, you can use IIFE.

(function(namespace) { // begin IIFE
// These values inside can not be accessed from global.
// But we do need a way to access these values, we add all values to 'namespace',
namespace.Game = Game;
// we pass window to this IIFE, so 'namespace == 'window' inside it.
// namespace can be anyword, it is just a parameter.
// since 'window' is value exist in global, all data we appended to it can be access from global via 'window'.
// You can pass any object, or anything, it is just an argument, just like you invoke a function. e.g. if we pass 'Steam'( an object created before), then we can run 'Steam.Game'.
})(window);    // end IIFE
// later we can ,
// window.Game 
sfy
  • 2,810
  • 1
  • 20
  • 22