zoukankan      html  css  js  c++  java
  • let、const和块级作用域

    函数作用域

    作用域,顾名思义就是一套规则,用于确定在何处(哪个作用域中),如何查找变量的规则(遵循作用域链)。

    ES6以前,javascript只有两种作用域,全局作用域和函数作用域,也有人叫本地作用域。

    函数作用域在带来便利的同时,也会造成一些匪夷所思的错误。

    var a = []
    for(var i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i)
      }
    }
    
    a[2]() // 10
    a[6]() // 10
    

    这里,我们通过var声明了i变量,js只有函数作用域,自然i是在全局范围内都有效的变量。for循环语句内每次循环,
    i的值都会加1,直到i等于10后跳出循环。循环内有一个匿名函数,每次循环均打印出i,这里的i与全局下的i建立了引用关系。
    导致函数推出后,i的值仍然存在。循环完成后的i = 10,所以无论如何调用都返回10。

    这是很不符合直觉的,因为我们写了循环,通常就只想在for循环内部的上下文中使用变量i,但实际上i可以在全局作用域下访问,
    污染了全局作用域。

    块级作用域

    let

    ES6引入了let关键字,可以将变量绑定在它所处的任意作用域内(一般是{...}内),实现块级作用域。

    这么做的意义在于,避免因为变量提升导致外层作用域读取内层作用域的变量,其次,内层变量无法覆盖外层变量。

    在代码块({...})中使用let声明变量,那么变量便会陷入「暂时性死区」,即在使用let声明的块级作用域内,他所声明的变量就绑定在这个区域中,不再受外部影响,
    而区域内阻止变量被访问(否则报错),除非访问行为发生在声明语句之后。

    var apple = 123
    
    if(true) {
      // apple = 321 // Uncaught ReferenceError
    	let apple = 321
    	console.log(apple) // 321
    	apple = 'banana'
    	console.log(apple) // banana
    }
    

    let的其它特性

    1. 不允许重复声明:通过var重复声明变量,不会发生报错,且后声明的会覆盖前面的。而用let重复声明则会报错;
    2. 不允许变量提升
    console.log(bar); // 报错ReferenceError
    let bar = 2;
    

    const

    const声明一个只读的常量,一旦声明了,它的值不能改变。它拥有一些和let类似的特性,具体如下:

    1. 一旦声明,常量的值就不得改变,否则报错,且声明的同时必须完成初始化;
    2. 声明后,变量同样会绑定块级作用域,仅在块级内有效;
    3. 声明的变量不提升,同样存在暂时性死区;
    4. 不可重复声明;

    const保证的并不是变量的值不被改变,而是变量指向的内存地址不得改动。因此,对于简单类型的数据,
    值值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。

  • 相关阅读:
    oracle中number数据类型简单明了解释
    计算机专业课程体系介绍(含学习顺序)
    浮点数的二进制表示
    C语言中为什么float型数据的范围是3.4E-38~3.4E+38
    C语言学习笔记
    近期学习计划
    二进制、八进制、十进制、十六进制之间转换
    MySQL 字段值为NULL,PHP用json转换,传给js,显示null
    写出float x 与“零值”比较的if语句——一道面试题分析
    BOOL,int,float,指针变量 与“零值”比较的if语句
  • 原文地址:https://www.cnblogs.com/CharmanderS5/p/9077343.html
Copyright © 2011-2022 走看看