Home  >  Article  >  Web Front-end  >  Block-level scope binding in JavaScript ES6

Block-level scope binding in JavaScript ES6

巴扎黑
巴扎黑Original
2017-08-21 09:39:181163browse

This article mainly introduces the in-depth understanding of block-level scope binding in ES6 study notes, which has certain reference value. Interested friends can refer to it

As we all know, the var statement in js There is a variable promotion mechanism, so ESMAScript 6 references block-level scope to strengthen control over the variable life cycle
let const declaration will not be promoted, there are several points to note

1. It cannot be declared repeatedly.

Assume that an identifier already exists in the scope (whether the identifier is declared through var or let or const variables). At this time, use let or A const key declaration will throw an error


var count=10
let count=20// 此处则会抛出错误,因为同一作用域内不能重复声明

If the current scope is embedded in another scope, you can use let to declare the same name in the embedded scope. Variables


var count=10
if(true){
  let count=20
}

2. Constants declared as const must be initialized

If declared as follows, an error will be reported


const name;//语法错误,常量未初始化

3. You cannot assign a value to a constant defined by const. The real essence is that the const declaration does not allow modification of the binding, but allows modification of the value (that is, the const declaration After the object is created, you can modify the attribute value of the object)


const person={
 name:'angela'
}
//可以修改对象属性的值
person.name='yun'
// 修改绑定则会抛出语法错误
person={
 'name':'Shining'
}

4. Temporal Dead Zone

When the JavaScript engine scans the code and finds variable declarations, it will either raise them to the top of the scope (var declarations are encountered), or place the declarations in the TDZ (let and const declarations are encountered), accessing the TDZ The variable will trigger a runtime error. Only after the variable declaration statement is executed, the variable will be moved out of the TDZ and can be accessed normally.
The following code is because the value is already in the TDZ when console.log is executed in the if block-level scope. In the past, typeof was a relatively error-prone operator, but it actually couldn't stop the engine from throwing errors

Accessing block-level bindings before declaration will cause errors because the bindings are in the temporary dead zone


if (true) {
 console.log(typeof value)//引用错误
 let value = 'blue'
}

If you use typeof on the variable outside the scope declared by let, no error will be reported


console.log(typeof value)
if (true) { 
 let value = 'blue'
}

5. Block-level scope binding

Before, creating functions in a loop was a bit unspeakable


var funcs = []
for (var i = 0; i < 10; i++) {
 funcs.push(function () {
  console.log(i)
 })
}
funcs.forEach(function (func) {
 func()
})

Because of the loop All functions created internally retain references to the same variables. At the end of the loop, the value of variable i is 10, so the result will be output 10 times 10

, so everyone will use the immediate call function in the loop expression to force a copy of the counter variable to be generated so that 1, 2, 3...


var funcs = []
for (var i = 0; i < 10; i++) {

 funcs.push((function (value) {
  return function () {
   console.log(value)
  }
 })(i))

}
funcs.forEach(function (func) {
 func()
})

With let, the function expression is called immediately It can be simplified. In fact, each iteration of the loop will create a new variable and initialize it with the value of the variable with the same name in the previous iteration.


var funcs = []
for (let i = 0; i < 10; i++) {
//其实是每次循环的时候let声明都会创建一个新变量i并将其初始化为i的当前值,所以在循环内部创建的每个函数都能得到属于它们自己的i的副本
 funcs.push(function () {
  console.log(i)
 })
}
funcs.forEach(function (func) {
 func()//这里输出是0 然后是1、2....9
})

This feature also applies to for in , for example


var funcs = [],
 obj = {
  a: true,
  b: true,
  c: true
 }
for (let key in obj) {
 funcs.push(function () {
  console.log(key)
 })
}
funcs.forEach(function (func) {
 func()//输出的是a b c
})

6. The let declaration feature in a loop also applies to const declarations. The only difference is that const cannot change the binding

In the above example, changing let to const also outputs a b c


var funcs = [],
 obj = {
  a: true,
  b: true,
  c: true
 }
//之所以可以运用for in 和for of循环中,是因为每次迭代不会修改已有绑定,而是会创建一个新绑定
for (const key in obj) {
 funcs.push(function () {
  console.log(key)// 同样输出a b c 唯一的区别是循环内不能更改key的值
 })
}
funcs.forEach(function (func) {
 func()
})

The following example will report an error because it is changed in the for loop. The binding of i but const constant cannot change the binding


var funcs = []
for (const i = 0; i < 10; i++) {
 funcs.push(function () {
  console.log(i)
 })
}
funcs.forEach(function (func) {
 func()
})

7. Global scope binding

When var is applied to the global scope, it creates a new global variable that acts as a property of the global object (the window object in the browser environment), which means that using var is likely to inadvertently overwrite an existing global variable

It can be seen from the code above that even the global object RegExp Array will be overwritten

But let or const will be created in the global scope A new binding, but the binding will not be added as a property of the global object. In other words, using let or const cannot overwrite the global variable, but can only obscure it

RegExp and window.RegExp at this time are different


##

let RegExp=&#39;hello&#39;
console.log(RegExp) //hello
console.log(window.RegExp===RegExp)//false

const ncz=&#39;hi&#39;
console.log(ncz)
console.log("ncz" in window)

Best practice:

Use by default let instead of var


uses const by default. Use let

only when you really need to change the value of the variable.

The above is the detailed content of Block-level scope binding in JavaScript ES6. For more information, please follow other related articles on the PHP Chinese website!

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