JS中 var let const
来源于 https://juejin.im/post/5d76a5dcf265da03ec2e8c2b 整理为自己可以理解的范围
在ES5中,用
var
关键字声明的变量存在变量提升,函数及变量的声明都将被提升到函数的最顶部,这就导致可以在使用之后在声明变量,这种不规范的行为很多时候都依靠编程习惯来约束
于是let
与const
应运而生,二者的作用域都是 当前代码块域 ,let
声明的变量可以修改,const
声明的是常量,声明后不可修改
let foo = 10;
const bar = {key: 20};
foo = 20;
bar.key = 30;
bar = 30; // TypeError
bar.key = 30
这句话改变的不是bar
的值,只是修改了其中的属性
JavaScript
中 存在函数作用域 而没有块级作用域
以function
声明的就是一个函数作用域
可以看到代码1
和代码2
是两个不同的块级作用域, 但是都是同一个函数作用域
function fn() {
console.log(fnA); // undefined
console.log(fnC); // undefined
console.log(fnD); // fnD is not defined
// 代码1
var fnA = 100;
var fnB = 200;
if (true) {
// 代码2
var fnC = 300;
let fnD = 400;
}
console.log(fnA); // 100
console.log(fnB); // 200
console.log(fnC); // 300
console.log(fnD); // ReferenceError
}
let
声明的语句在if
语句外面是不能被访问的ReferenceError
引用错误的报错, 表示引用了一个没有声明的变量
console.log(a); // undefined
console.log(b); // ReferenceError
console.log(c); // ReferenceError
var a = 100;
let b = 200;
const c = 300;
可以看到
console.log(a)
输出的是undefined
, 说明使用var
声明的变量 一开始就会被提升到代码的最前面 变量提升
但是let
和const
声明的变量 不存在 变量提升 必须先声明后使用, 否则就会报错 :ReferenceError
var a = 100;
var a = 200;
let b = 1000;
let b = 2000; // SyntaxError
使用
var
声明的变量可以重复声明赋值
但是let
和const
声明的变量不可以重复的声明赋值 会报语法错误SyntaxError
let 的简单理解
let
没有变量提升的说法
console.log(a) // undefined
var a = 100
console.log(b) // ReferenceError 引用错误
let b = 100
let
块级作用域
在没有块级作用域的
ES5
中 内层变量可能会覆盖外层变量
在存在块级作用域的ES6
中 当存在多个代码块的时候 , 不同代码块的变量不受其他代码块的影响
ES6
明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
// 1. 在没有块级作用域的 ES5 中
// 内层变量可能会覆盖外层变量
function fnc() {
var a = 100
if(true) {
var a = 200
}
console.log(a)
}
fnc() // 200
// 2. 在存在了 块级作用域的 ES6 中
function fnc() {
let a = 100
if(true) {
let a = 200
}
console.log(a)
}
fnc() // 100
let
暂时性死区现象
let
暂时性死区现象 就是在块级作用域下产生的
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}