Home >Web Front-end >JS Tutorial >A brief analysis of the difference between function declaration and function expression in JavaScript_javascript skills

A brief analysis of the difference between function declaration and function expression in JavaScript_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:07:261099browse

I remember when I was interviewing as an intern at Tencent, the interviewer asked me this question.

Copy code The code is as follows:

//What is the difference between the following two declaration methods

function foo(){};

var bar = function foo(){}; 

At first I only knew of two declaration methods: function declaration and function expression. I couldn’t explain the specific differences. I happened to see a book on this topic recently and wanted to summarize it.

In ECMAScript, there are two most commonly used methods to create function objects, namely using function expressions or using function declarations. In this regard, the ECMAScript specification makes it clear that the function declaration must always have an identifier (Identifier), which is what we call the function name, and the function expression can be omitted.

Function declaration:

Copy code The code is as follows:

function Identifier (FormalParameterList opt){ FunctionBody }

The function declaration parsing process is as follows:

 1. Create a new Function object, FormalParameterList specifies the parameters, and FunctionBody specifies the function body. Uses the scope chain in the currently running environment as its scope.

 2. Create an attribute named Identifier for the current variable object, with the value Result(1).

Function expression:

(Function expressions are divided into anonymous and named function expressions)

Copy code The code is as follows:

function Identifier opt(FormalParameterList opt){ FunctionBody } //Here is the named function expression

The parsing process of named function expressions 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, specify the parameters in FormalParameterList, and specify the function body in FunctionBody. Uses the scope chain in the currently running execution environment as its scope.
4. Create an attribute named Identifier for Result(1), its value is Result(3), read-only, cannot be deleted
5. Remove Result(1)
from the scope chain 6. Return Result(3)

The official documentation is very difficult to read. Simply put, ECMAScript distinguishes the two through context: if function foo(){} is part of an assignment expression, it is considered a function expression. And if function foo(){} is contained within a function body, or is located in (the top level of) the program, it is parsed as a function declaration. Obviously, when the identifier is omitted, the "expression" can only be an expression.

Copy code The code is 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 New expression (NewExpression)

(function(){
Function bar(){}; // Declaration, because it is part of the function body (FunctionBody)
})();

There is another situation:

Copy code The code is as follows:

(function foo(){})

This case is also a function expression, which is a function enclosed in a pair of parentheses. In its context, () constitutes a grouping operator, and the grouping operator can only contain expressions. More Example:

Copy code The code is as follows:

function foo(){}; // Function declaration

(function foo(){}); // Function expression: note that it is included in the grouping operator

try {
(var x = 5); // Grouping operators can only contain expressions, not statements (var here is a statement)
}
catch(err) {
// SyntaxError (because "var x = 5" is a statement, not an expression - evaluating an expression must return a value, but evaluating a statement does not necessarily return a value. - Translation
}

Let’s briefly talk about the similarities and differences between function declarations and function expressions. There is a subtle yet important difference in the behavior of declarations and expressions.

First, function declarations are parsed and evaluated before any expressions are parsed and evaluated. Even if the declaration is the last line in the source code, it will be evaluated before the first expression in the same scope. It is easier to understand by looking at an example. In the following example, the function fn is declared after alert. However, when alert is executed, fn is already defined:

Copy code The code is as follows:

alert(fn()); //Output Helloworld!

function fn() {
return 'Helloworld!';
}


To summarize briefly, what is the difference?

1. Declarations are always parsed at the beginning of the scope;
2. Expressions are evaluated only when encountered.

Function declaration has another important feature, that is, the behavior of controlling function declaration through conditional statements is not standardized, so different results may be obtained in different environments. That is:

Copy code The code is as follows:

// Never do this!
// Different browsers will return different results,

if (true) {
function foo() {
return 'first';
}
}
else {
function foo() {
return 'second';
}
}
foo();


// Remember to use function expressions in this case:
var foo;
if (true) {
foo = function() {
return 'first';
};
}
else {
foo = function() {
return 'second';
};
}
foo();

So, what are the actual rules for using function declarations?

FunctionDeclaration can only appear in Program or FunctionBody. Syntactically, they cannot appear inside a Block ({ ... }), for example, within an if, while, or for statement. Because Block can only contain Statement, but not SourceElement such as FunctionDeclaration.

On the other hand, if you take a closer look at the generation rules, you will find that the only way for an Expression to appear in a Block is to make it part of an ExpressionStatement. However, the specification clearly states that ExpressionStatement cannot start with the keyword function. What this actually means is that FunctionExpression cannot appear in Statement or Block (don't forget that Block is composed of Statement).

Due to the above restrictions, whenever a function appears in a block (like in the example above), it should actually be treated as a syntax error rather than a function declaration or expression.

 

 So when should we use function declarations or function expressions? Function declarations can only appear in "program code", which means they can only appear in other function bodies or in the global space; their definitions cannot be assigned to a variable or attribute, or passed as a parameter in a function call; the following An example is the allowed usage of function declarations. foo(), bar() and local() are all declared through the function declaration mode:

Copy code The code is as follows:

//Global environment
function foo() {}

function local() {
// Local environment
Function bar() {}
         return bar;
}

When you cannot syntactically use a function declaration, you can use a function expression. For example: pass a function as a parameter or define a function in an object literal:


Copy code The code is as follows:

// This is an anonymous function expression
callMe(function () {

//Pass a function as parameter
});

// This is a named function expression
callMe(function me() {

// Pass a function as parameter, the function name is me
});

// Other function expressions
var myobject = {
Say: function () {

// I am a function expression
}
};

My knowledge is limited, please correct me if there are any mistakes.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn