JS - self invoking function vs regular function

时间:2015-09-01 21:20:33

标签: javascript self-invoking-function

I'm a little confused.

Everywhere i look, people say that i should use self invoking functions for scoping reasons, to avoid global namespace pollution.

But in this aspect, self invoking function seems to act identically to regular function, as in this example:

function xx(){

    var x="variable";
    //logs into console
    console.log(x);
    }

xx();
//logs undefined
console.log(x);

So, only real difference with regular function and self invoking is "self invoking" part, meaning i just don't have to run function manually after declaration?

4 个答案:

答案 0 :(得分:2)

A “self-invoking function” is a name for a common JavaScript idiom. It’s not actually a type of function; it’s the immediate execution of a function. You can call it an IIFE for “immediately invoked function expression” instead if that helps.

(function () { // Anonymous function expression
    // IIFE!
})(); // Invocation happens here with the ()!
var f = (function () { // Still anonymous
    // Almost immediately invoked function expression!
});

f(); // Invocation happens here!
var f = (function f() { // Not anonymous – now called “f”
    // Almost immediately invoked function expression!
});

f(); // Invocation happens here!
function f() { // Not anonymous
    // Almost immediately invoked function *declaration* – not an expression!
}

f(); // Invocation happens here!

答案 1 :(得分:1)

Self-invoking functions are normal functions, but don't have a name. That makes them impossible to call except immediately after being declared, which effectively makes them a one-time-use function that is forever hidden from other code.

As you point out, the form

function foo() {
  console.log("foo");
}
foo()

and

(function () {
  console.log("foo");
})()

behave identically.

However, the first form with function foo() {... creates a named function that lives in that scope until the scope is destroyed. For the global scope, that will never happen, leaving foo a valid and callable identifier for any other code in your application.

That means that at any time, anybody else can do

foo()

and either initialize your module again or, potentially, obtain a handle to a new copy of the module.

At best, this can cause confusion and duplicate state. At worst, depending on how your IIFE is structured, they may be able to dig into hidden state and start manipulating it in ways you don't expect.

Writing a function that is both anonymous and immediately invoked prevents anyone from ever invoking it again, making it a clean and safe way to create and use a completely hidden scope. That's why you see it used so often to provide private state or construct a module.

答案 2 :(得分:0)

They must have confused a IIFE with "self-invoking function".

Here's something Ben Alman wrote:

What’s wrong with “Self-executing anonymous function?”

You’ve already seen it mentioned a few times, but in case it wasn’t clear, I’m proposing the term “Immediately-Invoked Function Expression”, and “IIFE” if you like acronyms. The pronunciation “iffy” was suggested to me, and I like it, so let’s go with that.

What is an Immediately-Invoked Function Expression? It’s a function expression that gets invoked immediately. Just like the name would lead you to believe.

I’d like to see JavaScript community members adopt the term “Immediately-Invoked Function Expression” and “IIFE” in their articles and presentations, because I feel it makes understanding this concept a little easier, and because the term “self-executing anonymous function” isn’t really even accurate:

  // This is a self-executing function. It's a function that executes (or
  // invokes) itself, recursively:

  function foo() { foo(); }

  // This is a self-executing anonymous function. Because it has no
  // identifier, it must use the  the `arguments.callee` property (which
  // specifies the currently executing function) to execute itself.

  var foo = function() { arguments.callee(); };

  // This *might* be a self-executing anonymous function, but only while the
  // `foo` identifier actually references it. If you were to change `foo` to
  // something else, you'd have a "used-to-self-execute" anonymous function.

  var foo = function() { foo(); };

  // Some people call this a "self-executing anonymous function" even though
  // it's not self-executing, because it doesn't invoke itself. It is
  // immediately invoked, however.

  (function(){ /* code */ }());

  // Adding an identifier to a function expression (thus creating a named
  // function expression) can be extremely helpful when debugging. Once named,
  // however, the function is no longer anonymous.

  (function foo(){ /* code */ }());

  // IIFEs can also be self-executing, although this is, perhaps, not the most
  // useful pattern.

  (function(){ arguments.callee(); }());
  (function foo(){ foo(); }());

  // One last thing to note: this will cause an error in BlackBerry 5, because
  // inside a named function expression, that name is undefined. Awesome, huh?

  (function foo(){ foo(); }());

Source : http://benalman.com/news/2010/11/immediately-invoked-function-expression/

答案 3 :(得分:-1)

// defined at `window`
function xx() {

  var x = "variable";
  //logs into console
  console.log(x);
}

xx();
// not defined at `window`
(function yy() {

  var y = "variable";
  //logs into console
  console.log("y:",y);
  // `window["yy"]` : `undefined`
  console.log("yy:", yy, "window['yy']:?", window["yy"]);
}());

console.log("xx", xx, window["xx"]);
try {
  console.log("yy:", yy, window["yy"]);
} catch (e) {
  console.log("yy:", e)
}
try {
  console.log("x:", x);
} catch (e) {
  console.log("x:", e)
}