• let 与 var


    前言
    let与var最大的区别就是var会变量提升、var会被覆盖、var变量没有块级作用域,而let都将弥补这些bug。
    传统语言都不会有‘变量提升、重复声明被覆盖、变量没有块级作用’这些问题,这是js的bug(js说这锅我不背,这是es6出的标准,我只是实现它)
    js里边只有全局作用域和函数作用域
    而传统编程语言是存在块级作用域的,所谓块级,就是用{xxx}里边的,比如语句、函数、代码块{ }。
    但是js只有函数里的变量享有块级作用域的待遇,其他均没有,这是个bug。后来es6除了个let弥补了这些bug。

    最经典的代码,使用var

     var arr=[];
     for(var i=0; i<3; i++){
          arr[i]=function () {
                console.log(i);
          }
     }
    arr[1]() //打印3

    原因解析,执行流程:
    因为js不存在块级作用的概念,所以i其实是存在于全局作用域的。

    当i=0
    arr[0]=function(){console.log(0)}

    当i=1
    ---arr[0]=function(){console.log(1)}---
    arr[1]=function(){console.log(1)}

    当i=2
    ---arr[0]=function(){console.log(2)}---
    ---arr[1]=function(){console.log(2)}---
    arr[2]=function(){console.log(2)}

     

    当循环完毕后
    i<3然后i++,所以for循环结束后,i最终结果为3。!!!!!!注意i已经为6了
    arr[0]=function(){console.log(3)}
    arr[1]=function(){console.log(3)}
    arr[2]=function(){console.log(3)}
    arr[3]=function(){console.log(3)}


    每次循环都会导致本轮循环的i覆盖掉全局的i,所以当循环完毕后在执行 arr[无论是几](),结果都是3

    ---xxx---表示该素组元素对应的函数里的i值将会被本轮循环里的i覆盖



    如果使用let,则不会发生上边的情况

    var arr=[];
     for(let i=0; i<3; i++){
          arr[i]=function () {
                console.log(i);
          }
     }
    arr[1]() //打印1

    原因解析,执行流程:
    这是因为用let的变量i,会形成块级作用域,i不在是全局的了。每次循环都不会导致本轮循环的i覆盖掉全局的i,各是个的。不会被覆盖。

    那么循环结束后,执行某一个arr[?]( )它都能够记住并打印出当时的那轮循环的那次i的值呢?
    阮一峰说:这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。再简单点,就是JavaScript 引擎内部记住了 



    言外话
    闭包,就是函数嵌套函数,因为函数存在作用域,所以大家都喜欢用闭包来模拟块级作用域
    let没出来之前,这确实有必要,let出来之后,闭包的意义就不是太大了



  • 相关阅读:
    Python自制小时钟,并转换为exe可执行程序详解
    Linux下搭建jmeter
    adb server is out of date. killing完美解决
    Python通过百度Ai识别图片中的文字
    robotframework在3.7下的搭建
    VIVO 手机重力传感器踩坑记录
    GPU 实现 RGB -- YUV 转换 (OpenGL)
    iOS UImage 与 RGB 裸数据的相互转换
    CVPixelBuffer的创建 数据填充 以及数据读取
    glReadPixel 读取数据错误问题
  • 原文地址:https://www.cnblogs.com/dshvv/p/7568342.html
Copyright © 2020-2023  润新知