Can a function be declared in a block-scoped scope? This is a rather confusing question.
ES5 states that functions can only be declared in the top-level scope and function scope, not at the block-level scope.
1 //situation one2 if(true) {3 functionf () {}4 }5 6 //Scenario Two7 Try {8 functionf () {}9}Catch(e) {Ten // ... One}
The above two function declarations, according to the provisions of ES5 are illegal.
However, the browser does not adhere to this rule, in order to be compatible with the old code, or to support the declaration of the function in the block-level scope, so the above two cases can actually run, no error.
ES6 introduces a block-level scope that explicitly allows functions to be declared within a block-level scope. ES6 specifies that in block-level scopes, function declaration statements behave similarly to let
non-referencing at the block-level scope.
1 functionF () {Console.log (' I am outside! '); }2 3(function () {4 if(false) {5 //declare function f repeatedly6 functionF () {Console.log (' I am inside! '); }7 }8 9 f ();Ten}());
The above code runs in ES5 and gets "I am inside!" because the if
function declared inside f
will be promoted to the function head, and the code actually running is as follows.
1 // ES5 environment 2 function f () {Console.log (' I am outside! ' 3 4 ( function () { 5 function f () {Console.log (' I am inside! ' 6 if ( false 7 } 8 F (); 9 } ());
ES6 is completely different, and in theory will be "I am outside!". Because a function declared within a block-level scope is similar to let
, there is no effect on the scope. However, if you really run the above code in the ES6 browser, it will be an error, this is why?
It turns out that if you change the processing rules for a function declared within a block-level scope, it will obviously have a big impact on old code. In order to alleviate the incompatibility problem, ES6 in Appendix B, the implementation of the browser can not comply with the above provisions, have their own way of behaving.
- Allows you to declare a function within a block-level scope.
- A function declaration is similar to
var
, that is, promoted to the head of a global scope or function scope.
- Also, the function declaration is promoted to the head of the block-level scope at which it resides.
Note that the above three rules are only valid for ES6 browser implementations, other environment implementations are not respected, or function declarations of block-level scopes are treated as let
processing.
According to these three rules, in a browser's ES6 environment, a function declared within a block-scoped scope behaves like var
a declared variable.
// ES6 Environment of the browser function f () {Console.log (' I am outside! ' ); } (function () { if (false) { // Repeated declaration of function f functions f () {Console.log (' I am inside! ') ); } } f ();} ()); // uncaught typeerror:f is not a function
The above code in the ES6 browser, will be an error, because the actual operation is the following code.
// ES6 Environment of the browser function f () {Console.log (' I am outside! ' ); } (function () { var f = undefined; if (false) { function f () {Console.log (' I am inside! ' ); } } f ();} ()); // uncaught typeerror:f is not a function
You should avoid declaring functions within a block-level scope, considering that the behavior caused by the environment is too different. If you do, you should write a function expression instead of a function declaration statement.
// function declaration Statement { = ' secret '; function f () { return A; }} // function Expression { = ' secret '; function () { return A; };}
In addition, there is a need to pay attention to the place. The block-level scope of ES6 allows you to declare the rules of a function only if you use curly braces, and if you do not use curly braces, you will get an error.
// do not error ' use strict '; if (true) { function f () {}}// error ' use strict '; if (true) function f () {}
(Above is ECMAScript 6 introductory text)
One of the ES6 records-block-level scopes and function declarations