0

All the JS files for a project I just started on start and end with the following lines, could anyone tell me what is happening here? I think it has something to do with OOP Javascript, but I'm not sure.

(function(pageName, $, undefined) {

    // Page logic

}(window.pageName = window.pageName || {}, jQuery));
Christian
  • 101
  • 1
  • 1
  • 8
  • Are you confused by the assignment inside a function parameter, `(window.pageName = window.pageName || {}`, or by the entire thing? – user229044 Jan 26 '15 at 18:40
  • You define a function, and then the second set of parenthesis executes it with the given parameters. – Fallenreaper Jan 26 '15 at 18:40

3 Answers3

3

That's defining a scoping function and calling it immediately with some arguments. The purpose of a scoping function is largely to contain the things that are inside it to avoid creating globals.

So let's look at the arguments it passes:

window.pageName = window.pageName || {}

That will either pass the existing window.pageName property, if it has a truthy* value, or a new object ({}) if it doesn't, using JavaScript's curiously-powerful || operator, which results in its left-hand operand if that operand is truthy, or its right-hand operand if not. So within the scoping function, pageName will always be truthy (and probably be an object).

jQuery

that's the non-$ variable for jQuery. Sometimes you need to use jQuery's noConflict mode (which releases the $ global) to integrate with other libraries. So doing this lets you use $ within the scoping function knowing that it will be equal to jQuery, even if $ outside the scoping function isn't.

Now about that third undefined: Note that it never actually passes an argument to match that named argument. That means the value of the undefined argument will be the value undefined. This basically insures that the symbol undefined within the scoping function really has the value undefined (since until ES5 [~2009], you could overwrite it with some other value!).


* "truthy" - In JavaScript, a value is "truthy" if it coerces to true when you use it as a boolean. Truthy values are values that aren't "falsey" (quelle surprise!). The falsey values are 0, NaN, null, undefined, "", and of course, false.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
2

It is code to use a customized object stored in window.pageName. When the object has already been instantiated, that object is passed in. If the object does not exist, then a new object is passed in. It also closes over jQuery, and ensures that no one changed the definition of undefined.

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • doesn't really explain what is happening here. You should simply point him to the answer of 'what is an IIFE' – Pinoniq Jan 26 '15 at 18:38
  • 1
    @Pinoniq You're assuming it's the IIFE that is confusing, and not the rest of the code, which is itself pretty odd to the uninitiated. – user229044 Jan 26 '15 at 18:40
  • There's quite a bit more going on here than just an IIFE, and this answer covers those in more detail. There happens to also be an IIFE, which could be mentioned. – ssube Jan 26 '15 at 18:40
  • @Pinoniq The definition of an IIFE does not explain why these particular values are being passed in as parameters and why undefined is purposely not passed in. – pdoherty926 Jan 26 '15 at 18:40
2

Here's what's happening.

First - create an anonymous function (or IIFE) that accepts three parameters (pageName, $, and undefined)

(function(pageName, $, undefined) {...

When the function is called, pass in window.pageName (unless it's null or undefined, then pass in an empty object) as the first parameter, then pass in jQuery as the second parameter. The third parameter is not passed in intentionally as a way to declare a local variable within the function that is undefined.

...}(window.pageName = window.pageName || {}, jQuery));

So, window.pageName becomes the local variable pageName, jQuery becomes the local variable $ and undefined is a variable that exists just as a shortcut so you don't have to check typeof someVariable === 'undefined' throughout the function. Instead, you can now perform a check like someVariable === undefined.

All of this is done without cluttering up the global space which is why you're seeing it throughout the code you're working on. I hope this helps clear it up a bit for you.

You should probably read more on Immediately Invoked Function Expressions (IIFE) or (how it was called when I learned - Self Executing Anonymous Functions). There are a ton of resources out there about this topic.

Howard Renollet
  • 4,609
  • 1
  • 24
  • 31