深切明白ES6笔记(一)块级作用域绑定

重要知识点有:var变量提拔、let声明、const声明、let和const的比较、块级绑定的运用场景

《深切明白ES6笔记(一)块级作用域绑定》

《深切明白ES6》笔记 目次

var

JavaScript中,我们一般说的作用域是函数作用域,运用var声明的变量,无论是在代码的哪一个处所声明的,都邑提拔到当前作用域的最顶部,这类行动叫做变量提拔(Hoisting)

function test() {
    var a
    //a声明没有赋值
    console.log('1: ', a) //undefined
    if (false) {
      a = 1
    }
    //a声明没有赋值
    console.log('3: ', a) //undefined
}

test()

假如a没有声明,那末就会报错,没有声明和声明后没有赋值是不一样的,这点肯定要区离开,有助于我们找bug。

//b提拔到函数a顶部,但不会提拔到函数test。
function test() {
    function a() {
      if (false) {
        var b = 2
      }
    }
    console.log('b: ', b)
}

test() //b is not defined

let

let和const都能够声明块级作用域,用法和var是相似的,let的特点是不会变量提拔,而是被锁在当前块中。

function test() {
    if(true) {
      console.log(a)//TDZ,俗称暂时死区,用来形貌变量不提拔的征象
      let a = 1
    }
}
test()  // a is not defined

function test() {
    if(true) {
      let a = 1
    }
    console.log(a)
}    
test() // a is not defined

唯一准确的运用方法:先声明,再接见

function test() {
    if(true) {
      let a = 1
      console.log(a)
    }
}
test() // 1

const

声明常量,一旦声明,不可变动,而且常量必需初始化赋值。

const type = "ACTION"

从新赋值会报错

const type = "ACTION"
type = 1
console.log(type) //"type" is read-only

const type = "ACTION"
let type = 1
console.log(type) //Duplicate declaration "type"

const虽然是常量,不许可修正默许赋值,但假如定义的是对象Object,那末能够修正对象内部的属性值。

const type = {
  a: 1
}
type.a = 2 //没有直接修正type的值,而是修正type.a的属性值,这是许可的。
console.log(type) // {a: 2}

const声明不许可修正绑定,但许可修正绑定的值

const和let的异同点:

相同点:const和let都是在当前块内有效,实行到块外会被烧毁,也不存在变量提拔(TDZ),不能反复声明。

不同点:const不能再赋值,let声明的变量能够反复赋值。

暂时死区(TDZ)

暂时死区的意义是在当前作用域的块内,在声明变量前的地区叫做暂时死区。

if (true) {
  //这块地区是TDZ,接见a会报错
  let a = 1
}

接见TDZ中的变量会触发运行时毛病
但下面这类不会报错

console.log(typeof a) //undefined,因为此时a不在TDZ中
if (true) {
  //这块地区是TDZ,接见a会报错
  let a = 1
}

块级作用域的运用场景

除了上面提到的经常使用声明体式格局,我们还能够在轮回中运用,最着名的一道面试题:轮回中定时器闭包的考题

在for轮回中运用var声明的轮回变量,会跳出轮回体污染当前的函数。

for(var i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i) //5, 5, 5, 5, 5
  }, 0)
}
console.log(i) //5 i跳出轮回体污染外部函数

//将var改成let以后
for(let i = 0; i < 5; i++) {
  setTimeout(() => {
    console.log(i) // 0,1,2,3,4
  }, 0)
}
console.log(i)//i is not defined i没法污染外部函数

轮回内const声明
在一般的for轮回中运用const变量,因为const变量不可修正,因此会报错。而在for-in或许for-of轮回中能够运用const变量。
因为轮回为每次迭代建立了一个新的变量绑定,而不是试图去修正已绑定的变量的值

let arr = [1,2,3,4];
 for(const item of arr){
     console.log(item); //输出1,2,3,4
 }

全局块作用域绑定

用var作用域全局作用域时声明的全局变量会掩盖一个已存在的全局属性:

var reg = "hello";
console.log(window.reg) //"hello"

而假如在全局作用域运用let或许const声明,当声明的变量自身就是全局属性,比方closed。会建立一个新的绑定,但不会增加全局属性;就是说,用let或const不能掩盖全局变量,只能遮盖它;

window.closed = false
let closed = true

closed // true
window.closed // false

最好实践

在现实开辟中,我们挑选运用var、let照样const,取决于我们的变量是否是须要更新,一般我们愿望变量保证不被歹意修正,而运用大批的const,声明一个对象的时刻,也引荐运用const,当你须要修正声明的变量值时,运用let,var能用的场景都能够运用let替换。

    原文作者:sevencui
    原文地址: https://segmentfault.com/a/1190000015979322
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞