3

Can someone explain in detail what this snippet of js does?

(function (window) {
    var test = window['test'] = {};
    test.utils = new(function(){ ... })();
})(window);

I understand that the function is not globally scoped. I understand that it is creating a variable called test that points to a property in the window object that is an empty object. I also understand that utils is a property of test.

I don't understand what the purpose of the last part is (window); or why the utils function is being designated as new.

Please explain.

bflemi3
  • 6,698
  • 20
  • 88
  • 155
  • 1
    It's a slightly misguided attempt to make the code in the anonymous (outer) function "safe" from tampering with `window`. It's misguided because it fails to do that :-) Instead of passing `window`, the code should pass `this`. – Pointy Feb 07 '13 at 14:56
  • Neither do I understand. Where did you get that code from, and what does the constructor-invoked function expression contain? – Bergi Feb 07 '13 at 14:57
  • possible duplicate of [What does this mean? (function (x,y)){...}){a,b); in JavaScript](http://stackoverflow.com/questions/3921922/what-does-this-mean-function-x-y-a-b-in-javascript) – Felix Kling Feb 07 '13 at 14:58
  • 2
    `new(function(){ ... })();` is just defining the constructor function and creating an instance in one go. It's the same as `function Foo() {...}` and `new Foo();`. Using an object literal might be easier here, but I cannot tell since I don't know what's the content of the function. – Felix Kling Feb 07 '13 at 15:00
  • possible duplicate of [JS function definition : meaning of the last parentheses](http://stackoverflow.com/questions/14103575/js-function-definition-meaning-of-the-last-parentheses) – sdespont Feb 07 '13 at 15:01
  • thats the second time i see someone using an IEFE, adding properties to a passed (global) `window` Object, the first time it was from some javascript videotutorial, i wonder where this comes from – Moritz Roessler Feb 07 '13 at 15:05
  • this comes from a variation of old knockoutjs code – bflemi3 Feb 07 '13 at 15:21

4 Answers4

2

It creates a function and calls it immediately, passing in window. The function receives an argument called window and then creates an empty object on it which is available both as a property on window called test and as a local variable called test. Then it creates an object by calling a function via new and assigns that object to test.utils.

I don't understand what the purpose of the last part is (window);...

It doesn't really serve any purpose in the code you've quoted, because the symbol passed into the main (outer) function, window, is the same as the name of the argument receiving it. If their names were different, then it would serve a purpose, e.g.:

(function(wnd) {
})(window);

That would make window available within the function as wnd.

or why the utils function is being designated as new.

utils won't be a function (at least, not unless the code you've replaced with ... is doing something really strange), it will be an object created by calling that function.

The whole thing could be rewritten more clearly:

(function(window) {

    var test;

    test = {};
    window['test'] = test;

    test.utils = new NiftyThing();

    function NiftyThing() {
    }

})(window);

That still does the window thing for no reason, but hopefully it makes it clear what the new(function() { ... })(); bit was doing.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • If you use the `window` variable, it might help minification. That's the only reason I've heard of, yet I think such things should be done by the minifier :-) – Bergi Feb 07 '13 at 15:33
  • so what would be the difference between `test.utils = new(function(){ ... })();` and `test.utils = function(){ ... };`? – bflemi3 Feb 07 '13 at 17:17
  • @bflemi3: In the first, `test.utils` will refer to an object that almost certainly isn't a function. In the second, `test.utils` will refer to a function. – T.J. Crowder Feb 07 '13 at 17:43
1

First of all, this is a self-invoked function.

It's invoked itself giving the window object as function input argument in order to ensure that, inside the whole function, window will have the expected meaning.

test.utils = new(function(){ ... })(); <--- This is an object constructor. 

When the function is called using the new operator, it turns into an object constructor.

For example:

var conztructor = function() {
   this.name = "Matias";
};

var obj = new conztructor();
alert(obj.name); // <--- This will alert "Matias"!

The purpose of (window); is creating a new variable and reference holding the JavaScript Window object instance, avoiding that other libraries may reuse the window (or any other) identifier and your own library may break because of this situation.

This is nice in order to avoid altering global scope identifiers that may be used by other libraries.

UPDATE

In response to some comments, run this code:

http://jsfiddle.net/wChh6/5/

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
  • Why do you think the `window` variable avoids modifications of the global object? – Bergi Feb 07 '13 at 15:10
  • ^^^^^--- Its passed as reference, modifications will apply to the global object too, thats why i don't understand the purpose behind this http://jsbin.com/emaqog/1/edit – Moritz Roessler Feb 07 '13 at 15:11
  • @Bergi Ok, maybe I explained it in the wrong way. I mean that you avoid overwriting the identifier and change what window or anything is designed for. – Matías Fidemraizer Feb 07 '13 at 15:12
  • @Glutamat Check my update, now I explain it better than before :) – Matías Fidemraizer Feb 07 '13 at 15:16
  • No, that's wrong. You never will be able to overwrite the global `window` identifier. – Bergi Feb 07 '13 at 15:18
  • @Bergi thats where i stumbled upon it the first time. MikeBoutin posted a videotutorial link in the javascript [chat](http://chat.stackoverflow.com/transcript/message/7510222#7510222) this is the [video](http://www.gotoandlearn.com/play.php?id=159) it should be around 8:30 – Moritz Roessler Feb 07 '13 at 15:18
  • @Bergi Try the code in jsFiddle I posted some minutes ago :) See if you can or not. – Matías Fidemraizer Feb 07 '13 at 15:25
  • 1
    http://jsfiddle.net/wChh6/3/ -> that doesn't change anything, you cant set `window` to `null`. And i don't really see any purpose, in setting the copied reference to the `window` Object to null, either – Moritz Roessler Feb 07 '13 at 15:25
  • @Glutamat You didn't understand the sample. It's about showing that reusing the `window` identifier inside the self-executing function, executed before the last alert, doesn't change the window identifier in the global scope. I mean, the VARIABLE holds Window yet! – Matías Fidemraizer Feb 07 '13 at 15:28
  • @Glutamat: Thanks for the link. The reason for using `window` is explained at 5:20 - and it's trivial :-) – Bergi Feb 07 '13 at 15:30
  • @Glutamat In response to **And i don't really see any purpose, in setting the copied reference to the window Object to null, either**. Open your mind, man. Setting `window` to null is pointless, but some library could set `window` to whatever, for example a custom object, and if it's not done inside a self-invoked function creating a local var `window`, the rest of the libraries will stop working. – Matías Fidemraizer Feb 07 '13 at 15:36
  • @MatíasFidemraizer you're overwriting the reference to the window Object, but that still does not make much sense to me, why would you pass an Object just to destroy its reference, you could've just created a local variable then – Moritz Roessler Feb 07 '13 at 15:38
  • so its just for the convenience of havin the variable called window ? Oh i just saw Bergis comment, i'll look at 5:20 maybe that makes things clear to me =) – Moritz Roessler Feb 07 '13 at 15:41
  • @Glutamat I'm agree that reusing the `window` identifier isn't a very good practice, but it's for the sake of the sample. Anyway, jQuery both defines `window` and `undefined` as local variables and arguments for the self-invoked function, meaning that they prefer to practice defensive programming and avoid other libraries breaking their own library code. Since `window` or `undefined` aren't keywords, bad coding can break others' one, why not preventing it? It's crazy, but that's the reason!!! :D – Matías Fidemraizer Feb 07 '13 at 15:47
  • @Glutamat Good programmers won't reuse window reference for storing nothing different than standard window object, but as I said, since other would do, you don't declare a local variable holding `window` for later setting other object, but for just avoiding that other stupid library would change `window` global scope variable and your code would get absolutely wrong. – Matías Fidemraizer Feb 07 '13 at 15:50
  • @MatíasFidemraizer Noooow i get it =) Thx for that!!! =) fortunately ES5 specifies `undefined` as not-writable, maybe we're safer in the future (+1) – Moritz Roessler Feb 07 '13 at 15:53
  • @Glutamat W00000000000t!! Finally hahaha Thanks for understanding it ;) – Matías Fidemraizer Feb 07 '13 at 19:19
  • @Glutamat Yeah, and hopefully sometime JavaScript will be a modern, solid and more predictable language. But if you know the "shit", you can do great things with JS. See the strict mode, for example. – Matías Fidemraizer Feb 07 '13 at 19:20
0

What is happening here is that a new anonymous function is being declared. The last part with (window) makes a call to that function, passing window as a parameter.

Inside, the call to test.utils = new(function(){ ... })(); creates a new object (with contents defined by the function passed to new) and assigns it to test.utils.

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
0

When you define a function with last parentetheses, the function is executed itself after loading with the parameter given, in your case window

(function (window) {
    var test = window['test'] = {};
    test.utils = new(function(){ ... })();
})(window);

JS function definition : meaning of the last parentheses

Community
  • 1
  • 1
sdespont
  • 13,915
  • 9
  • 56
  • 97