当前位置:   article > 正文

js知识点汇总之let const 和 var的区别

js知识点汇总之let const 和 var的区别

let const 和 var的区别

作用域

ES5 中的作用域有:全局作用域、函数作用域,ES6 中新增了块级作用域。块作用域由 { } 包括,if 语句for 语句里面的 { } 也属于块作用域。

var关键字

  1. 没有块级作用域的概念
// global scope
{
	var a = 10;
}
console.log(a); // 10

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在全局中输出a为10说明var不存在块级作用域的概念

  1. 有全局作用域,函数作用域的概念

    var b = 20;
    function test() {
    	var a = 10;
    	console.log(a);
    	console.log(b);
    }
    test();
    console.log(a);
    // 10 20 a is not defined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  2. 不初始化值默认为 undefined,存在变量提升

    console.log(a); //undefined
    var a;
    a = 10;
    
    • 1
    • 2
    • 3
  3. 全局作用域用 var 声明的变量会挂载到 window 对象下

//Global Scope
var a = 10;
console.log(a);  //10
console.log(window.a);  //10
console.log(this.a);  //10
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 同一作用域中允许重复声明
//Global Scope
var a = 10;
var a = 20;
console.log(a);  //20

checkscope();
function checkscope(){
    //Local Scope
    var b = 10;
    var b = 20;
    console.log(b);  //20
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

上面代码中,在 Global Scope 中声明了 2a,以最后一次声明有效,打印为 20。同理,在 Local Scope 也是一样的。

let 关键字

  1. 有块级作用域的概念
{
   //Block Scope
   let a = 10;
}
console.log(a);  //ReferenceError: a is not defined
  • 1
  • 2
  • 3
  • 4
  • 5

上面代码中,打印 a 报错,说明存在 Block Scope 的概念。

  1. 不存在变量提升(不可以在声明之前使用)
{
  //Block Scope
  console.log(a);  //ReferenceError: Cannot access 'a' before initialization
  let a = 10;
}
  • 1
  • 2
  • 3
  • 4
  • 5

上面代码中,打印 a 报错:无法在初始化之前访问。说明不存在变量提升。

  1. 暂时性死区
{
  //Block Scope
  console.log(a);  //ReferenceError: Cannot access 'a' before initialization
  let a = 20;
}

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

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

  a = 123;
  console.log(a);  //123
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

上面代码中,使用 let 声明的变量 a,导致绑定这个块级作用域,所以在 let 声明变量前,打印的变量 a 报错。

这是因为使用 let/const 所声明的变量会存在暂时性死区。

什么叫做暂时性死区域呢?翻译成人话就是:

当程序的控制流程在新的作用域(module、functionblock 作用域)进行实例化时,在此作用域中用 let/const 声明的变量会先在作用域中被创建出来,但因此时还未进行词法绑定,所以是不能被访问的,如果访问就会抛出错误。因此,在这运行流程进入作用域创建变量,到变量可以被访问之间的这一段时间,就称之为暂时死区。

再简单理解就是:

ES6 规定,let/const 命令会使区块形成封闭的作用域。若在声明之前使用变量,就会报错。
总之,在代码块内,使用 let/const 命令声明变量之前,该变量都是不可用的。
这在语法上,称为 “暂时性死区”temporal dead zone,简称 TDZ)。

其实上面不存在变量提升的例子中,其实也是暂时性死区,因为它有暂时性死区的概念,所以它压根就不存在变量提升了。

  1. 同一块作用域中不允许重复声明
{
  //Block Scope
  let A;
  var A;  //SyntaxError: Identifier 'A' has already been declared
}
{
  //Block Scope
  var A;
  let A;  //SyntaxError: Identifier 'A' has already been declared
}
{
  //Block Scope
  let A;
  let A;  //SyntaxError: Identifier 'A' has already been declared
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

const 关键字

  1. 必须立即初始化,不能留到以后赋值
// Block Scope 
const a; // SyntaxError: Missing initializer in const declaration } 
  • 1
  • 2

上面代码中,用 const 声明的变量 a 没有进行初始化,所以报错。

  1. 常量的值不能改变
//Block Scope 
{
  const a = 10; 
	a = 20; // TypeError: Assignment to constant variable
}
  • 1
  • 2
  • 3
  • 4
  • 5

上面代码中,用 const 声明了变量 a 且初始化为 10,然后试图修改 a 的值,报错。

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/644674
推荐阅读
相关标签
  

闽ICP备14008679号