每日一句
For the things that make you sad, one day, you will laugh out and say it.
释义:让你难过的事情,总有一天你会笑着说出来。
前言
var, let 在js中都是用来声明变量的,let是es6中新增出来的,为啥会出来let呢,var是有啥缺陷?
var
- 声明的变量是全局的,且window顶层也能访问
- 声明变量后还可以再声明(相同{}[作用域内]内会变量污染)
var a=1;
console.log(a); // 1
console.log(window.a); // 1
console.log(window['a']); // 1
if (true) {
// 重新定义了a
var a = 8;
console.log(a); //8
}
console.log(a) //8
- 可以在变量声明前,使用变量(变量会提升)
console.log(a); // undefined
var a = 5;
- 函数内声明的变量是局部变量,外层访问报错
(function() {
var a = 888;
console.log(a) // 888
})()
console.log(a);
- 函数内不用声明也是全局变量(不建议,严格模式报错,es6警告)
(function(){
a = 999
})()
console.log(a)
console.log(window.a)
console.log(window['a'])
- 声明的全局变量可能会造成变量污染
for (var i=0; i<3; i++) {
setTimeout(() => console.log(i), 0) // 3 3 3
}
console.log(i); // 3
let
- 声明的全局变量,window顶层没有这个属性
- 声明后的变量,在不同的{}中,只会在{}中生效
let a = 1;
console.log(a) // 1
console.log(window.a) // undefined
console.log(window['a']) // undefined
if (true) {
// 重新定义
let a = 8
console.log(a) // 8
}
console.log(a) // 1
- 声明后的变量,在相同的{}中,直接报错
let a = 1;
let a = 8;
console.log(a) // Uncaught SyntaxError: Identifier 'a' has already been declared
- 未声明,先引用,报错
console.log(a); // Uncaught ReferenceError: a is not defined
let a = 9;
- 函数内声明的变量是局部变量,外层访问报错
(function() {
let a = 888;
console.log(a) // 888
})()
console.log(a);
- 声明的全局变量只会在{}生效,不会造成变量污染
for (let i=0; i<3; i++) {
setTimeout(() => console.log(i), 0) // 0 1 2
}
console.log(i); // ReferenceError: i is not defined
总结
VAR VS LET
相同点:
-
在js中都是用来声明变量,函数内声明是局部变量
-
不在{}或函数内声明的变量是全局变量
不同点:
-
var声明的全局变量会顶层对象的属性,而let声明的变量不是顶层对象的属性
-
非函数内,let声明的变量在{}中生效,{}之外不生效,而var声明的变量会生效
-
var声明的变量会提升,不会报错,而let声明的变量不会提长,报错
-
[非严格模式]var声明的变量可以重新声明,不会报错,其值是最后一次声明的值,而let不可以再次声明,会报错
从var与let的不同点出发,我们知道了为啥es6会出来let关键字,正因为var声明的变量可能潜在污染变量,给开发带来严重的影响,当然还有其他原因,进而es6推出let来声明。
扩展
顶层对象:浏览器的顶层对象是window,Node中的是global对象
ES5中的顶层对象的属性等价于全局变量。
ES6中,var function
声明的全局变量依然是顶层对象的属性;
let const class import
声明的全局变量不属于顶层对象的属性。
也就是说ES6开始,全局变量和顶层对象的属性开始分离,脱钩。
ES5声明变量只有两种方式:var 和 function
,
var
变量提升, function
是提升 + 定义。
ES6 声明变量的方式有:let const import class
再加上ES5的var function
一共是有6种声明变量的方式
const
声明的变量不可以修改,而且必须初始化。