Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I read Javascript Closure Syntax?

Based on some code in a lecture by Doug Crockford, I've created this.

var isAlphaUser = (function() {
    alert("Forming Alpha User List");
    let AlphaUsers = {
        1234: true,
        5678: true
    };

    return function(id){
        alert("Checking Alpha Users:",id); 
        return AlphaUsers[id];};
}());

alert("starting");
alert(isAlphaUser(1234));
alert(isAlphaUser(5678));
alert(isAlphaUser(3456));

which gives me this:

Forming Alpha User List
starting
Checking Alpha Users: 1234
true
Checking Alpha Users: 5678
true
Checking Alpha Users: 3456
undefined

Which is quite cool, as it does the expensive setup once only, and every further call is a cheap check.

However, I can't decipher the code that does this. Specifically, I can't understand why I need the "()" at the end of the function declaration.

Can somebody explain how this syntax is working?

like image 751
deworde Avatar asked Jul 14 '11 17:07

deworde


People also ask

How do you read closures?

A closure is a feature in JavaScript where an inner function has access to the outer (enclosing) function's variables — a scope chain. The closure has three scope chains: it has access to its own scope — variables defined between its curly brackets. it has access to the outer function's variables.

How do you use closures in JavaScript?

This is called a JavaScript closure. It makes it possible for a function to have "private" variables. The counter is protected by the scope of the anonymous function, and can only be changed using the add function. A closure is a function having access to the parent scope, even after the parent function has closed.

What is code closure?

A closure is a programming technique that allows variables outside of the scope of a function to be accessed. Usually, a closure is created when a function is defined in another function, allowing the inner function to access variables in the outer one.

When closures are used in JavaScript?

In JavaScript, closures are the primary mechanism used to enable data privacy. When you use closures for data privacy, the enclosed variables are only in scope within the containing (outer) function. You can't get at the data from an outside scope except through the object's privileged methods.


2 Answers

() calls a function. function() { } defines a function. Appending () right after immediately calls it1, and the result (also an anonymous function) is assigned to isAlphaUser.

The function() { ... }() pattern is frequently used to isolate variables to an inner scope, so those variables don't become part of the global scope.

In this case, this is what happens:

  1. An anonymous function is run, defining a variable AlphaUsers inside that scope.
  2. That function returns another function that takes 1 parameter. This function is a closure to which the AlphaUsers variable becomes bound (in other words, available). This function checks if the parameter passed in is contained in AlphaUsers (actually, it returns the item at that index, which is just a boolean).
  3. The return value is assigned to a variable isAlphaUser.
  4. Since isAlphaUser is now a function, it can be called to see if the parameter is contained in the AlphaUsers variable, but no direct access to AlphaUsers is available in the global scope (it become a sort of private variable).

1 — Note: As cwolves mentioned in the comments, beware that while () appended directly after the } works in this case, it is only because in this case the function definition is a function expression. If function is the first word on the line, the line becomes a function declaration, and that is all that line can do, the function is not anonymous (it will require a name, otherwise it's a syntax error) and cannot be called immediately inline. See Function Declarations vs. Function Expressions for more info.

like image 90
Nicole Avatar answered Nov 03 '22 00:11

Nicole


The () at the end of the code is separate from the closure issue. By wrapping your function in parens and adding the () at the end you are creating an anonymous function that is run immediately with whatever arguments you pass into ().

like image 33
dave Avatar answered Nov 02 '22 23:11

dave