Function

原文链接:http://dailyjs.com/post/function

We've already been using functions and methods (remember the difference?) as part of this series, but it's time to take a deeper look at one of my favourite parts of the language. Prepare to have your mind blown by two incredible facts about the humble function.

Functions are Objects

The ECMAScript Language Specification defines three ways to create functions. The first is a function declaration:

function sum(a, b) {
  return a + b;
}

A Function object will be instantiated behind the scenes, and returned as the result of this expression. With that in mind, the following should make complete sense:

var sum = function(a, b) {
  return a + b;
};

The function expression results in a value being returned, and it can be assigned as required. That's because the function's identifier is optional, and also because a Function object is returned.

The Function constructor isn't hidden away by the interpreter, however. It can be used like this:

var sum = new Function('a', 'b', 'return a + b');

That brings us to an important point: functions are objects. They're not a pre-OO construct that's used to somehow build JavaScript's object-oriented features -- they're actually objects themselves and can be manipulated as such.

When functions are passed as arguments or set to variables, they're colloquially known as anonymous functions. This term isn't used within the ECMAScript specification, but you'll see it referred to when people discuss popular APIs like jQuery:

$('selector').each(function() {
  // Inside the anonymous function passed to jQuery's `each` method
});

Closures

Functions can be created anywhere an expression can appear, which means they can appear inside other functions:

function sum(a, b) {
  function max() {
    return a > 100 || b > 100;
  }

  if (max()) {
    throw new ArgumentError('Value too large');
  }
  return a + b;
}

We've already used this when creating "private" functions inside prototype methods and constructors. However, notice how the arguments to sum are visible inside the max function. Internally, the function is passed the VariableEnvironment of the current context, which is otherwise known as the scope.

The fact these inner functions receive access to the variables in their containing function's scope is useful, and known as a closure:

Let closure be the result of creating a new Function object as specified in 13.2 with parameters specified by FormalParameterListopt and body specified by FunctionBody. Pass in funcEnv as the Scope.

References

Fork me on GitHub