var,let,const区别

110 阅读2分钟

声明变量的关键字

js中声明变量的方式:var let const

最初声明变量的关键字就是 var,但是为了解决作用域的问题,所以后面新增了 letconst 的方式。

作用域

ES5:全局作用域,函数作用域

ES6:新增块级作用域

var

  1. 没有块级作用域
{
  var a = 10;
}
console.log(a); // 10
  1. 存在全局作用域,函数作用域
var a = 10;
function test(){
  var b = 20;
  console.log(a);// 10
  console.log(b);// 20
}
test()
console.log(a);// 10
console.log(b);// ReferenceError: b is not defined
  1. 不初始化默认值为undefined
var a;
console.log(a);//  undefined

这里 undefinedundefined 类型,而不是字符串。

  1. 存在变量提升(js在编辑阶段的时候,会搜集所有的变量声明,并且提前声明变量)
console.log(a);// undefined
var a = 10;
function test(){
  console.log(a); //10
  conosle.log(b); //undefined
  var b = 20;
}
  1. 全局作用域下,var声明的变量会挂载到window对象下
var a = 10;
console.log(a);  //10
console.log(window.a);  //10
console.log(this.a);  //10
  1. 同一作用域下允许重复声明
var a = 1;
var a = 2;
console.log(a)// 2

let

  1. 存在块级作用域
{
   let a = 10;
}
console.log(a);  //ReferenceError: a is not defined
  1. 不存在变量提升
console.log(a) // ReferenceError: Cannot access 'a' before initialization
let a = 1;
  1. 暂时性死区(使用let/const声明变量之前该变量都是不可用的)
{
  //Block Scope
  console.log(a);  //ReferenceError: Cannot access 'a' before initialization
  let a = 20;
}

if (true) {
  //TDZ开始(TDZ:暂时性死区)
  console.log(a);  //ReferenceError: Cannot access 'a' before initialization

  let a; //TDZ结束
  console.log(a);  //undefined

  a = 123;
  console.log(a);  //123
}
  1. 同一块级作用域下不能重复声明
{
  let A;
  var A;  //SyntaxError: Identifier 'A' has already been declared
}
{
  var A;
  let A;  //SyntaxError: Identifier 'A' has already been declared
}
{
  let A;
  let A;  //SyntaxError: Identifier 'A' has already been declared
}

const

  1. 声明之后必须立即初始化,不能之后赋值
const a; // SyntaxError: Missing initializer in const declaration }
  1. 常量的值不能改变
{
  const a = 10; 
	a = 20; // TypeError: Assignment to constant variable
}

const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动

  • 对于基本数据类型 (数值、字符串、布尔值) ,值就保存在变量指向的那个内存地址,因此等同于常量
  • 对于引用数据类型(对象和数组) ,变量指向的内存地址,const只能保证这个指针是固定的,不能保证它指向的数据结构是不可变得