1.var 声明:用于定义变量,可用于保存任何类型的值。在没有赋予初始值会给予一个 undefined 。
2.let 声明:作用与var差不多。最大区别let声明为块级作用域,而var是函数作用域。
function run(){ var x=10 if(true){ let y=5 console.log(x,y) } console.log(x,y) } run()
由于let y作用域为块级作用域,只在if内部生效。所以超出作用域范围外报错。
3.const 声明:用于声明常量,且声明变量的时候必须初始化变量。如果后续修改变量会产生报错。作用域也为块级作用域。
function run(){ console.log(num) // undefined var num=10 } // 上述代码等同于下述代码 function run(){ var num console.log(num) //undefined num=10 }
数据提升:把所有变量声明都写到函数作用域顶部。
let没有数据提升的能力。
var name ="WangED" console.log(window.name) let age = 24 console.log(window.age)
for(var j=0;j<3;j++){ console.log(j) setTimeout(()=>console.log(j),0) }
for(let i=0;i<3;i++){ console.log(i) setTimeout(()=>console.log(i),0) }
主要造成差异的原因是因为:作用域不同。setTimeout为异步处理,拿到的是循环之后的值。
var 相当于变为全局变量,会被覆盖掉,所以setTimeout拿到的是最后覆盖的值。
// 等价于 var j for(j=0;j<3;j++){ console.log(j) setTimeout(()=>console.log(j),0) }
let 为块级作用域,每一个值都会存在于单独的作用域不会被覆盖掉,
{ let i=0 console.log(i) setTimeout(()=>console.log(i),0) } { let i=1 console.log(i) setTimeout(()=>console.log(i),0) } { let i=2 console.log(i) setTimeout(()=>console.log(i),0) }
由于let 在很多方面都强于 var 使得代码规范性更强。所以在ES6中基本全面淘汰var转为使用let,尽量不使用var。
而const由于强制保持变量不变的特性,可以让静态代码分析工具提前发现不合法的赋值。所以优先使用const来声明变量,在知道未来会修改变量值时候再用let。这样可以迅速发现因为意外赋值而导致的非预期效果。