www.runoob.com/w3cnote/es6…
www.runoob.com/js/js-let-c…
精简好记版
# let
- let 声明的变量只在 let 命令所在的代码块内有效。
- const 声明一个只读的常量,一旦声明,常量的值就不能改变。
let 是在代码块内有效,var 是在全局范围内有效:
let 只能声明一次 var 可以声明多次:
for 循环计数器很适合用 let
- setTimeout 定时器里面的 i 指的是全局变量 i ,而循环里的十个 setTimeout 是在循环结束后才执行,所以此时的 i 都是 10。
- 变量 j 是用 let 声明的,当前的 j 只在本轮循环中有效,每次循环的 j 其实都是一个新的变量,所以 setTimeout 定时器里面的 j 其实是不同的变量,即最后输出 12345。(若每次循环的变量 j 都是重新声明的,如何知道前一个循环的值?这是因为 JavaScript 引擎内部会记住前一个循环的值)。
let 不存在变量提升,var 会变量提升:
- 变量 b 用 var 声明存在变量提升,所以当脚本开始运行的时候,b 已经存在了,但是还没有赋值,所以会输出 undefined。
- 变量 a 用 let 声明不存在变量提升,在声明变量 a 之前,a 不存在,所以会报错。
const
const 声明一个只读变量,声明之后不允许改变。意味着,一旦声明必须初始化,否则会报错。
-
暂时性死区:ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。
-
注意要点
const 如何做到变量在声明初始化之后不允许改变的?其实 const 其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不允许改动。此时,你可能已经想到,简单类型和复合类型保存值的方式是不同的。是的,对于简单类型(数值 number、字符串 string 、布尔值 boolean),值就保存在变量指向的那个内存地址,因此 const 声明的简单类型变量等同于常量。而复杂类型(对象 object,数组 array,函数 function),变量指向的内存地址其实是保存了一个指向实际数据的指针,所以 const 只能保证指针是固定的,至于指针指向的数据结构变不变就无法控制了,所以使用 const 声明复杂类型对象时要慎重。
稀碎版:
# 概念相关: - 全局,局部看有无function - 块级作用域看有无{} - 块级作用域是随着let,const一块儿来的,等于是对以前的var的细分。 # 变量 ## var
- 函数外var的变量,函数内可以调用
- 函数内var的变量,函数外可以调用
- 函数内直接声明的变量 = 函数外var的变量
- var的特权( 变量提升:先调用后var )
- 有重新定义变量的问题(使用 var 关键字重新声明变量可能会带来问题。在块中重新声明变量也会重新声明块外的变量:)
let和const
- 在 ES6 之前,是没有块级作用域的概念的。
- let 声明的变量只在 let 命令所在的代码块 {} 内有效,在 {} 之外不能访问。
使用var关键字声明的全局作用域变量属于window对象。
使用let关键字声明的全局作用域变量不属于window对象。
使用var关键字声明的变量在任何地方都可以修改。
在相同的作用域或块级作用域中,不能使用let关键字来重置var关键字声明的变量。
在相同的作用域或块级作用域中,不能使用let关键字来重置let关键字声明的变量。
let关键字在不同作用域,或不用块级作用域中是可以重新声明赋值的。
在相同的作用域或块级作用域中,不能使用const关键字来重置var和let关键字声明的变量。
在相同的作用域或块级作用域中,不能使用const关键字来重置const关键字声明的变量
const 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的:
var关键字定义的变量可以先使用后声明。
let关键字定义的变量需要先声明再使用。
const关键字定义的常量,声明时必须进行初始化,且初始化后不可再修改。