var 、let 和 const 的区别

122 篇文章 2 订阅
117 篇文章 0 订阅
  • var 声明的范围是函数作用域,let 和 const 声明的范围是块作用域

  • var 声明的变量会被提升到函数作用域的顶部,let 和 const 声明的变量不存在提升,且具有暂时性死区特征

  • var 允许在同一个作用域中重复声明同一个变量,let 和 const 不允许

  • 在全局作用域中使用 var 声明的变量会成为 window 对象的属性,let 和 const 声明的变量则不会

  • const 的行为与 let 基本相同,唯一 一个重要的区别是,使用 const 声明的变量必须进行初始化,且不能被修改

关键字

变量提升

块级作用域

重复声明同名变量

重新赋值

var

×

let

×

×

const

×

×

×

1.作用域

**var**没有块级作用域,而**let声明的范围是块作用域;**一对大括号 就是 一个块级作用域

if (true) {
    var message = "hello";
    console.log(message); // hello
}
console.log(message); // hello


if (true) {
    let message = "hello";
    console.log(message); // hello
}
console.log(message); // error: message is not defined

let不允许同一个块作用域中出现冗余声明

if (true) { 
    // error: 无法重新声明块范围变量“a”
    let a;
    let a;
}

JS 引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错,这是因为同一个块中没有重复声明:

let a = 666;
console.log(a); // 666
if (true) {
    let a = '啊哈哈';
    console.log(a); // 啊哈哈
}

**varlet声明的并不是不同类型的变量,它们只是指出变量在相关作用域如何存在,所以对声明冗余报错不会因混用varlet**而受影响:

// error
var a;
let a;

// error
let b;
var b;

2.变量提升

//用var命名的变量有变量提升
console.log(num1);  // undefined
var num1 = 10;
// 以上代码运行时,相当于下面的写法
?
var num2;  // 声明提升到作用域最顶端
console.log(num2);  // undefined
num = 10;
/*****************************************/
//用 let 或 const 命名的变量有变量提升
console.log(num3); // Uncaught ReferenceError: num3 is not defined
let num3 = 10;      
?
console.log(num4); // Uncaught ReferenceError: num4 is not defined
const num4 = 10;

3.暂时性死区

只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量

var tmp = 123; // 声明
if (true) {
  tmp = 'abc'; // 报错 因为本区域有tmp声明变量
  let tmp; // 绑定if这个块级的作用域 不能出现tmp变量
}

**暂时性死区和不能变量提升的意义在于:**为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。

4.重复声明同名变量和重新赋值

//var 关键字可以声明同名变量,实际第二次声明是对第一次声明的变量重新赋值
var num1 = 10;
var num1 = 20;
console.log(num1);  // 20
?
//let 和const 关键字不能重复声明同名变量,即使之前是用var声明的也会报错
var num2 = 10;
let num2 = 20;  // Uncaught SyntaxError: Identifier 'num2' has already been declared 
?
//let 和 var 在声明变量时,可以不用初始化
let num3;  
console.log(num3);  // undefined
var num4;  
console.log(num4);  // undefined
?
//const 声明常量时必须初始化,因为 `const` 关键字声明的是常量,声明后不能再赋值
const num5;  // Uncaught SyntaxError: Missing initializer in const declaration
?

//let 声明的变量可以重新赋值
let num1 = 10;
num1 = 20;
console.log(num1);  // 20
//const 只能在声明时赋值,之后不能再重新赋值
const num2 = 10;
num2 = 20;  // Uncaught TypeError: Assignment to constant variable.

5.扩展

5.1.全局声明

使用var在全局作用域中声明的变量会成为window对象的属性,letconst声明的变量则不会:

var a = 666;
console.log(window.a); // 666

let b = 666;
console.log(window.b); // undefined

const c = 666;
console.log(window.c); // undefined

5.2.for 循环中的var和let 声明的区别

for (var i = 0; i < 5; i++) {
    setTimeout( () => {
        console.log(i); // 5、5、5、5、5
    }, 0 )
}

for (let i = 0; i < 5; i++) {
    setTimeout( () => {
        console.log(i); // 0、1、2、3、4
    }, 0 )
}

var是因为在退出循环时,迭代变量保存的是导致循环退出的值,也就是 5。在之后异步执行超时逻辑时,所有的i都是同一个变量,因此输出的都是同一个最终值。

而在使用let声明迭代变量时,JS 引擎在后台会为每个迭代循环声明一个新的迭代变量,每个 setTimeout 引用的都是不同的变量实例,所以 console.log 输出的是我们期望的值,也就是循环执行过程中每个迭代变量的值。

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值