1、var Js没有块级作用域
在JS函数中的var声明,其作用域是函数体的全部; 明明已经跳出 for 循环了,却还可以访问到 for 循环内定义的变量 a ,甚至连 i 都可以被放访问到
for(var i=0;i<10;i++){
var a = 'a';
}
console.log(a,i);
2. 循环内变量过度共享
for (var i = 0; i < 3; i++) {
debugger
console.log('0',i)
setTimeout(function () {
debugger
console.log(i)
}, 1000);
}
3、let解决了块级作用域以及for的问题
1、let 声明的变量有块级作用域 2、形如for (let x...)的循环在每次迭代时都为x创建新的绑定
4、const 就是用来定义常量的
5、变量提升
console.log(a);//正常运行,控制台输出 undefined
var a = 1;
console.log(b);//报错,Uncaught ReferenceError: b is not defined
let b = 1;
console.log(c);//报错,Uncaught ReferenceError: c is not defined
const c = 1;
6、暂时性死区
只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
var tmp = 123; // 声明
if (true) {
tmp = 'abc'; // 报错 因为本区域有tmp声明变量
let tmp; // 绑定if这个块级的作用域 不能出现tmp变量
}
7、重复声明:let 和 const 命令声明的变量不允许重复声明 var 是允许重复定义的
function func(){
let a = 10;
const PI = 3.1415;
var a = 1;// 报错,Uncaught SyntaxError: Identifier 'a' has already been declared
var PI = 3;// 报错,Uncaught SyntaxError: Identifier 'PI' has already been declared
}
// 当调用func()时报错,Uncaught SyntaxError: Identifier 'a' has already been declared
function func(){
let a = 10;
const PI = 3.1415;
let a = 1;// 报错,Uncaught SyntaxError: Identifier 'a' has already been declared
const PI = 3;// 报错,Uncaught SyntaxError: Identifier 'PI' has already been declared
}
var i = 10;
for(var i = 0;i < 5;i++){
console.log(i);
}
console.log(i);// 输出 5
6、初始值
const声明之后值不能改变 let和var 可以改变
const PI = 3.1415;
PI = 3;// 报错,Uncaught TypeError: Assignment to constant variable.
6、作用域
在 ES5 中只有全局作用域和函数作用域,没有块级作用域, 第一种场景,内层变量可能会覆盖外层变量。
var tmp = new Date();//处于全局作用域
function f() {
console.log(tmp);//处于函数作用域
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
第二种场景,用来计数的循环变量泄露为全局变量
var i = 10;
for(var i = 0;i < 5;i++){
console.log(i);
}
console.log(i);// 输出 5
6、为什么需要块级作用域
内层变量可能覆盖外层变量 用来计数的循环变量泄露为全局变量