let const 和var的区别

199 阅读2分钟

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、为什么需要块级作用域

内层变量可能覆盖外层变量 用来计数的循环变量泄露为全局变量