【JS】var和let区别详解

1、作用域

var 和 let 的作用域规则都是一样的,其声明的变量只在其声明的块或子块中可用。

但:

- var 声明的变量的作用域只能是全局或者整个函数块的。

-  let 声明的变量的作用域既可以是全局或者整个函数块,也可以是 if、while、switch等用{}包裹的代码块。

2、关于重复声明

var 允许在同一作用域中重复声明

而 let 不允许在同一作用域中重复声明,否则将抛出异常(Syntax Error)

3、绑定全局对象

当存在全局对象Window时,

var 在全局环境声明变量,会在全局对象里新建一个属性,即可以通过window和this的指向访问

而 let 在全局环境声明变量,则不会在全局对象里新建一个属性。

扫描二维码关注公众号,回复: 15255887 查看本文章
var foo = 'global'
let bar = 'global'

//此时this指向window对象
console.log(this.foo) // 输出:global
console.log(this.bar) // 输出:undefined

4、变量提升和暂存死区

var声明的作用域下,存在变量提升现象,即变量可以在声明之前调用,并且不会报错。

console.log(a) // undefined   (不会报错,但是还未赋值)

var a = 1;

console.log(a) // 1

let声明的作用域下,虽然变量依然在创建执行上下文的时候就被创建,但是在代码未执行到变量声明语句之前,变量不可访问。此不可访问阶段成为“暂存死区”。会报Reference Error

console.log(x);  // undefined
var x = 10;
function foo() {
    console.log(x);  //Reference Error:
//let导致外部var定义的x也不可访问
//如果去掉函数中的let x的定义,则可以打印外部定义的x=10
    let x = 20;
    x++;
}
foo();

*补充:理解变量提升现象

1、执行上下文:执行上下文有三类:全局执行上下文、函数执行上下文、eval 函数执行上下文

2、将执行上下文看作一个对象:包括变量对象、作用域链、this对象

 3、一个执行上下文的生命周期:

而用 var 声明的变量构建变量对象时进行的操作如下:

  • 由名称和对应值(undefined)组成一个变量对象的属性被创建(创建并初始化)
  • 如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。

上述过程就是我们所谓的“变量提升”,这也就能解释为什么变量可以在声明之前使用,因为使用是在执行阶段,而在此之前的创建阶段就已经将声明的变量添加到了变量对象中,所以执行阶段通过标识符可以在变量对象中查找到,也就不会报错。

参考博客:深入理解JS:var、let、const的异同 - OneForCheng - 博客园 (cnblogs.com) 

猜你喜欢

转载自blog.csdn.net/weixin_57208584/article/details/130049874
今日推荐