Does the variable wrapped in es6 if count as inside the block?

青灯夜游
Release: 2022-11-21 16:21:58
Original
1412 people have browsed it

es6 Within the variable calculation block wrapped by if. There is a new block-level scope in es6. The code wrapped by "{ }" is the block-level scope; the "{}", if statement, and code in the for loop in the function all belong to the block-level scope and are calculated within the block. In ES6, block-level scopes are allowed to be nested arbitrarily. The outer scope cannot read variables of the inner scope; the inner scope can define variables with the same name of the outer scope.

Does the variable wrapped in es6 if count as inside the block?

The operating environment of this tutorial: Windows 7 system, ECMAScript version 6, Dell G3 computer.

What is block-level scope

Block-level scope is added in ES6. The block scope is wrapped by { }, and the { } in the if statement and the for statement also belong to the block scope.

The {}, if statement, and for loop in the function also belong to the block-level scope. Variables defined by let and const can only be valid in the scope.

Why block-level scope is needed

The first scenario: internal variables will overwrite external variables

var time = new Date()
function fx () {
    console.log(time) // undefined
    if (false) {
        var time = 'hello'
    }
}
fx()
Copy after login
{
    var a = 1
    console.log(a) // 1
}
console.log(a) // 1
// 通过var定义的变量可以跨块作用域访问到。
Copy after login

Second Scenario: The loop variable used for counting leaks into the global variable

for. The variables defined with var in the loop can be accessed in the external scope

for (var i = 0; i < 3; i++) {

}

for (let j = 0; j < 3; j++) {

}
// 3
console.log(i);
// Uncaught ReferenceError: j is not defined
console.log(j);
Copy after login

if The variables defined by var in the statement can be accessed in the external scope

if(true) and ## The difference between #if (false)

  • if(true) The assignment statement will be executed, so a prints out 3
  • The assignment statement in if(false) will not be executed, but the declared variable var b will be promoted to The top level of the scope, so it prints out undefined
if (true) {
	var a = 3
}

if (false) {
	var b = 3
}
// 3
console.log(a);
// undefined
console.log(b);

if (true) {
	let c = 3
}
// Uncaught ReferenceError: c is not defined
console.log(c);
Copy after login

## block-level scope (ES6 provides let & const variables to implement block-level scope scope)
function fxFn () { // 这是一个块级作用域
    let fx = 'fx is a great girl'
    if (true) { // 这是一个块级作用域
        let fx = 'fx is 18 years old'
    }
    console.log(fx) // fx is a great girl
}
fxFn()
 
// 块级作用域之间相互不影响
Copy after login
ES6 allows arbitrary nesting of block-level scopes.

{{{{
  {
    let fnn = 'Hello'
  }
  console.log(fnn); // 报错
}}}};
Copy after login

The above code uses a five-level block-level scope, and each level is a separate scope. The fourth-level scope cannot read the internal variables of the fifth-level scope.

The inner scope can define variables with the same name as the outer scope.
  • {{{{
      let fnn = 'Hello';
      {
        let fnn = 'Hello'
      }
    }}}};
    Copy after login
  • The emergence of block-level scope actually makes the widely used anonymous immediately executed function expression (anonymous
IIFE

) no longer necessary. <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">// IIFE 写法 (function () {   var tmp = '...';   // ... }());   // 块级作用域写法 {   let tmp = '...';   // ... }</pre><div class="contentsignin">Copy after login</div></div>

Block-level scope and function declaration

ES5

stipulates that functions can only be used in top-level scopes and functions Declared in scope, cannot be declared in block-level scope. <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">// 情况一 if (true) {   function f() {} }   // 情况二 try {   function f() {} } catch(e) {   // ... }</pre><div class="contentsignin">Copy after login</div></div>The above two function declarations are illegal according to

ES5

. However, browsers do not comply with this requirement. In order to be compatible with old code, they still support declaring functions in block-level scopes. Therefore, the above two situations can actually run without reporting errors.

ES6

introduced block-level scope, explicitly allowing functions to be declared in block-level scope. ES6 stipulates that in the block-level scope, the function declaration statement behaves like let and cannot be referenced outside the block-level scope. <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">function f() { console.log('I am outside!'); }   (function () {   if (false) {     // 重复声明一次函数f     function f() { console.log('I am inside!'); }   }     f(); }());</pre><div class="contentsignin">Copy after login</div></div>When the above code is run in

ES5

, you will get "I am inside!" because the function ## declared within if #f will be promoted to the function head, and the actual running code is as follows.

// ES5 环境
function f() { console.log('I am outside!'); }
 
(function () {
  function f() { console.log('I am inside!'); }
  if (false) {
  }
  f();
}());
Copy after login
ES6 is completely different. In theory, you will get "

I am outside!". Because functions declared in block-level scope are similar to let, they have no effect outside the scope. However, if you actually run the above code in the ES6 browser, an error will be reported. Why is this?

// 浏览器的 ES6 环境
function f() { console.log('I am outside!'); }
 
(function () {
  if (false) {
    // 重复声明一次函数f
    function f() { console.log('I am inside!'); }
  }
 
  f();
}());
// Uncaught TypeError: f is not a function
Copy after login
The above code will report an error in the ES6 browser.

It turns out that if the processing rules for functions declared in the block-level scope are changed, it will obviously have a great impact on the old code. In order to alleviate the resulting incompatibility problems, ES6 stipulates that browser implementations can not comply with the above regulations and have their own behavior

allowing functions to be declared in block-level scope.

    Function declaration is similar to
  • var
  • , that is, it will be promoted to the head of the global scope or function scope.
  • At the same time, the function declaration will also be promoted to the head of the block-level scope where it is located.
  • Note that the above three rules are only valid for browser implementations of
  • ES6
. Implementations in other environments do not need to comply. Block-level function declarations should still be regarded as

let handle. According to these three rules, in the browser's ES6

environment, functions declared in the block-level scope behave similarly to variables declared in

var. The code that actually runs in the above example is as follows.

// 浏览器的 ES6 环境
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
Copy after login
Considering that the behavior caused by the environment is too different, you should avoid declaring functions in block-level scope. If it is really necessary, it should be written as a function expression instead of a function declaration statement.
// 块级作用域内部的函数声明语句,建议不要使用
{
  let a = 'secret';
  function f() {
    return a;
  }
}
 
// 块级作用域内部,优先使用函数表达式
{
  let a = 'secret';
  let f = function () {
    return a;
  };
}
Copy after login

ES6 的块级作用域必须有大括号

如果没有大括号,JavaScript 引擎就认为不存在块级作用域。

// 第一种写法,报错
if (true) let x = 1;
 
// 第二种写法,不报错
if (true) {
  let x = 1;
}
Copy after login

上面代码中,第一种写法没有大括号,所以不存在块级作用域,而let只能出现在当前作用域的顶层,所以报错。第二种写法有大括号,所以块级作用域成立。

函数声明也是如此,严格模式下,函数只能声明在当前作用域的顶层。

// 不报错
'use strict';
if (true) {
  function f() {}
}
 
// 报错
'use strict';
if (true)
  function f() {}
Copy after login

【推荐学习:javascript视频教程

The above is the detailed content of Does the variable wrapped in es6 if count as inside the block?. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template