let & const —— ES6基础总结(二)

前言

在JS中,var早已深刻人心,所以本文将再也不赘述,仅在必要时拉出来溜溜。html

声明方式 变量提高 暂时性死区 重复声明 可修改值 块级做用域 全局变量属于顶层对象
var
let
const 否(引用类型仅保证地址不被修改)

变量提高

a   // a is not defined
    let a = 'a'
    
    b  // b is not defined
    const b = 'b'
    
    c   // undefined
    var c = 'c'
复制代码

暂时性死区

在代码块内,使用letconst命令声明变量以前,该变量都是不可用的。es6

其本质是,只要一进入当前做用域,所要使用的变量就已经存在了,可是不可获取,只有等到声明变量的那一行代码出现,才能够获取和使用该变量。web

typeof a    // a is not defined
    let a = 'a'
    
    typeof b    // b is not defined
    const b = 'b'
    
    typeof c    // "undefined"
    var c = 'c'
复制代码

如下为几个比较隐蔽的死区:浏览器

  1. 赋值闭包

    var a = a
    let b = b   // b is not defined
    复制代码
  2. 函数参数函数

    function foo(a = b, b = 2) {
      console.log([a, b])
    }
    foo()
    复制代码

重复声明

let a = 'a1'
    let a = 'a2'    // Identifier 'a' has already been declared
    a   // a1
    
    const b = 'b1'
    const b = 'b2'  // Identifier 'b' has already been declared
    b   // b2
    
    var c = 'c1'
    var c = 'c2'
    c   // c2
复制代码

修改值

let a = 'a1'
    a = 'a2'    
    a   // a2
    
    const b = 'b1'
    b = 'b2'  // Assignment to constant variable
    b   // b1
    
    var c = 'c1'
    c = 'c2'
    c   // c2
复制代码

const 引用类型仅保证引用地址不可修改ui

const a = {
       a1: 1,
       a2: 2
    }
    a.a3 = 3
    a   // {a1: 1, a2: 2, a3: 3}
复制代码

块级做用域

{
        let a = 'a'     
        const b = 'b'   
        var c = 'c'
    }
    a   // a is not defined
    b   // b is not defined
    c   // c
复制代码

全局变量再也不属于顶层对象

顶层对象:浏览器中指window,Node中指globalspa

let a = 'a'
    window.a    // undefined 
    
    const b = 'b'
    window.b    // undefined 
    
    var c = 'c'
    window.c    // "c"
复制代码

不再用担忧手抖修改了顶层对象~3d

解决的问题

  1. 内层变量覆盖外层变量;code

  2. 用来计数的循环变量变为全局变量;

    1. 上面代码中,变量j是let声明的,当前的j只在本轮循环有效,因此每一次循环的j其实都是一个新的变量,那么若是每一轮循环的变量j都是从新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是由于 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量j时,就在上一轮循环的基础上进行计算。
    1. for循环还有一个特别之处,就是设置循环变量的那部分是一个父做用域,而循环体内部是一个单独的子做用域。

  3. 闭包与垃圾回收;

    有块级做用域

    有块级做用域

    无块级做用域

    无块级做用域

  4. 再也不须要使用当即执行函数,减小代码冗余提高可读性;

  5. 容许在块级做用域中声明函数,函数声明语句的行为相似于let;

    原来,若是改变了块级做用域内声明的函数的处理规则,显然会对老代码产生很大影响。为了减轻所以产生的不兼容问题,ES6 在附录 B里面规定,浏览器的实现能够不遵照上面的规定,有本身的行为方式

    1.容许在块级做用域内声明函数。

    2.函数声明相似于var,即会提高到全局做用域或函数做用域的头部。

    3.同时,函数声明还会提高到所在的块级做用域的头部。

    注意,上面三条规则只对 ES6 的浏览器实现有效,其余环境的实现不用遵照,仍是将块级做用域的函数声明看成let处理。

参考

  1. ECMAScript 6 入门

  2. 你不知道的JavaScript(上)

小结

本文主要介绍了letconstvar定义变量的区别以及优势。推荐我用了两个月的时间才理解 let这篇文章,供你们思考。

以前声明变量只能使用varfunction,如今ES6添加了letconstimportclass4种方式(importclass 后续也会一一总结),因此如今总共有6种声明变量的方式。SO声明变量,请合理选择。

感谢阅读,若有问题,欢迎指正。

最最最最最后,在这四天的五一小长假里,为你们献上美景 —— 摩洛哥蓝色小镇🇲🇦祝你们五一愉快呦~

摩洛哥蓝色小镇
相关文章
相关标签/搜索