I remember interviewing Tencent interns when the interviewer asked me such a question.
Copy Code code as follows:
What is the difference between the two statements below?
function foo () {};
var bar = function foo () {};
Only two types of declarations were known. One is a function declaration, one is a function expression, and what's different is not very good. Recently happened to see this aspect of the book, just want to make a good summary.
In ECMAScript, there are two of the most commonly used methods of creating function objects, that is, using function expressions or using function declarations. In this regard, the ECMAScript specification makes it clear that a function declaration must always have an identifier (Identifier), which is what we call a function name, and a function expression can be omitted.
function declaration:
Copy Code code as follows:
function Identifier (formalparameterlist opt) {functionbody}
The function declaration parsing process is as follows:
1. Create a new function object, formalparameterlist the specified parameter, functionbody the specified function body. Takes the scope chain of the currently running environment as its scope.
2. Create a property named identifier for the current variable object, with a value of result (1).
function expression:
(function expressions are classified as anonymous and named function expressions)
Copy Code code as follows:
function Identifier opt (formalparameterlist opt) {functionbody}//Here is the named expression
The parsing process for a named function expression is as follows:
1. Create a new object
2. Add result (1) to the top of the scope chain
3. Create a new function object, formalparameterlist the specified parameter, functionbody the specified function body. Takes the scope chain of the currently running execution environment as its scope.
4. Create a property named identifier for result (1) with a value of result (3), read-only, not deleted
5. Remove result from the scope chain (1)
6. Return result (3)
Official documents are very clumsy to read. In simple terms, ECMAScript distinguishes between the two by context: if function foo () {} is part of an assignment expression, it is considered a function expression. If function foo () {} is contained in a function body, or at the top of the program, it is parsed as a function declaration. Obviously, in the case of omitting an identifier, the expression can only be an expression.
Copy Code code as follows:
function foo () {}; declaration because it is part of the program
var bar = function foo () {}; expression, because it is part of the assignment expression (assignmentexpression)
New function Bar () {}; expression, because it is part of the new expression (newexpression)
(function () {
function bar () {}; Declaration, because it is part of the function body (functionbody)
})();
There is also a situation:
Copy Code code as follows:
This is also a function expression, which is contained within a pair of parentheses, in its context, () constituting a grouping operator, and the grouping operator can only contain expressions, more examples:
Copy Code code as follows:
function foo () {}; function declaration
(function foo () {}); Function expression: Note that it is included in the grouping operator
try {
(var x = 5); The group operator can only contain expressions and cannot contain statements (where Var is the statement)
}
catch (Err) {
SyntaxError (because "var x = 5" is a statement, not an expression--evaluation of an expression must return a value, but a statement evaluation does not necessarily return a value.) --Translation
}
Here is a simple comparison between function declaration and function expression. There is a very subtle and important difference between the behavior of a declaration and an expression.
First, the function declaration is parsed and evaluated before any expression is parsed and evaluated . Even if the declaration is on the last line in the source code, it is evaluated before the first expression in the same scope. It's easier to see an example. In the following example, the function FN is declared after alert. However, when alert executes, FN is already defined:
Copy Code code as follows:
Alert (FN ()); Output helloworld!
function fn () {
Return ' helloworld! ';
}
What's the difference, simply summed up?
1. The Declaration always resolves at the beginning of the scope;
2. Expressions are only operational when encountered.
Another important feature of function declarations is that the behavior of controlling function declarations through conditional statements is not standardized, so different results may be obtained in different contexts . That is:
Copy Code code as follows:
Don't do this!
Different browsers will have different return results,
if (true) {
function foo () {
Return ' a ';
}
}
else {
function foo () {
return ' second ';
}
}
Foo ();
Remember, in this case, you use a function expression:
var foo;
if (true) {
foo = function () {
Return ' a ';
};
}
else {
foo = function () {
return ' second ';
};
}
Foo ();
So, what exactly is the actual rule that uses a function declaration?
Functiondeclaration (function declaration) can only appear in program (Programs) or functionbody (function body). In terms of clauses, they cannot appear in blocks (block) ({...}). , for example, you cannot appear in an if, while, or for statement. Because the block (blocks) can contain only statement (statements) and cannot contain sourceelement (the source element) such as functiondeclaration (function declaration).
On the other hand, a closer look at the resulting rule also finds that the only possible expression (expression) in the block (blocks) is to make it part of the expressionstatement (expression statement). However, the specification explicitly stipulates that expressionstatement (expression statements) cannot begin with a keyword function. And this in effect means that the functionexpression (function expression) also cannot appear in the statement (statement) or block (blocks) (don't forget that the block is composed of statement).
Because of this limitation, as long as the function appears in the block (as in the example above), it should actually be treated as a grammatical error rather than a function declaration or expression.
So when should we use a function declaration or a function expression? A function declaration can only appear in "program code", means that they can only be in other function bodies or in the global space; their definitions cannot be assigned to a variable or property, or as a parameter passed in a function call; The following example is the allowable use of a function declaration, Foo (), bar (), and local ( are declared by a function declaration pattern:
Copy Code code as follows:
Global Environment
function foo () {}
function local () {
Local environment
function bar () {}
return bar;
}
You can use a function expression when you cannot use a function declaration in grammar. For example, pass a function as an argument or define a function in the literal amount of an object:
Copy Code code as follows:
This is an anonymous function expression
CallMe (function () {
Passing a function as an argument
});
This is an expression of a named function
CallMe (function me () {
Pass a function as an argument, and the function name is me
});
Other function expressions
var MyObject = {
Say:function () {
I am a function expression
}
};
Learning is limited, if there is a mistake, please correct me.