[02] Block-level scope

[02] Block-level scope

Konjac summary:
Why have block scope?
  • 01, the inner variable covers the outer variable because the variable is promoted. Function promotion.
  • 02, the loop variable used for counting is leaked as a global variable. After the loop ends, it doesn't disappear, it leaks into a global variable.

03, ES6 allows arbitrary nesting of block-level scopes.
04. The inner scope can define a variable with the same name as the outer scope.
05. Immediately execute anonymous functions (IIFE) is no longer necessary.
06. The scope of the function is within the block-level scope of its definition.

It should be noted that if in strict mode, functions can only be declared in top-level scopes and functions, and declarations in other cases (such as if code blocks, loop code blocks) will report errors.





block scope
Why do you need block scope?
ES5 only has global scope and function scope, and no block-level scope, which brings many unreasonable scenarios.

In the first scenario, inner variables may override outer variables.
var tmp = new Date();

function f(){
  console.log(tmp);
  if (false){
    var tmp = "hello world";
  }
}

f() // undefined

In the above code, after the function f is executed, the output result is undefined that the reason is that the variable is promoted, which causes the tmp variable of the inner layer to cover the tmp variable of the outer layer.


In the second scenario, the loop variable used for counting is leaked as a global variable.
var s = 'hello';

for (var i = 0; i < s.length; i++){
  console.log(s[i]);
}

console.log(i); // 5

In the above code, the variable i is only used to control the loop, but after the loop ends, it does not disappear and leaks into a global variable.

ES6 block scope
let Actually added block-level scoping to JavaScript.
function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

The above function has two code blocks, both declare variables n , and output 5 when run. This means that the outer code block is not affected by the inner code block. If you use the var definition variable n , the final output value is 10.

ES6 allows arbitrary nesting of block scopes.
{{{{{let insane = 'Hello World'}}}}};

The code above uses a five-level block scope. The outer scope cannot read the variables of the inner scope.
{{{{{let insane = 'Hello World'}
  console.log(insane); // 报错
}}}};

Inner scopes can define variables of the same name in outer scopes.
{{{{let insane = 'Hello World';{let insane = 'Hello World';}}}}};





The advent of block-level scoping effectively makes the widely used Immediately Executed Anonymous Functions (IIFEs) unnecessary.
// IIFE写法
(function () {var tmp = ...;...}());
// 块级作用域写法
{let tmp = ...;...}




另外,ES6也规定,函数本身的作用域,在其所在的块级作用域之内。
function f() {
	console.log('I am outside!');
}
(function () {
	if (false) { // 重复声明一次函数f
		function f() {
			console.log('I am inside!');
		}
	}
	f();
}());


上面代码在ES5中运行,会得到“I am inside!”,但是在ES6中运行,会得到“I am outside!”。这是因为ES5存在函数提升,不管会不会进入  if 代码块,函数声明都会提升到当前作用域的顶部,得到执行;而ES6支持块级作用域,不管会不会进入if代码块,其内部声明的函数皆不会影响到作用域的外部。

{
  let a = 'secret';
  function f() {
    return a;
  }
}
f() // 报错

上面代码中,块级作用域外部,无法调用块级作用域内部定义的函数。如果确实需要调用,就要像下面这样处理。
let f;{let a = 'secret';
  f = function () {return a;}}f(); // "secret"



**

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325282127&siteId=291194637