JS作用域和变量提升,var let const

本文深入探讨了ES6中let和const声明的变量并不会像var那样进行变量提升,而是存在一个暂时性死区(TDZ)。在块级作用域内,变量在初始化之前访问会导致错误。const保证的不是值不变,而是变量引用的内存地址不变。理解这些概念对于正确使用ES6语法至关重要。
摘要由CSDN通过智能技术生成

不会变量提升?


经常看到有文章说: 用let和const申明的变量不会提升。其实这种说法是不准确的,比如下面代码:

var x = 1;
if(true) {
  console.log(x);
  
  let x = 2;
}


上述代码会报错Uncaught ReferenceError: Cannot access 'x' before initialization。如果let申明的x没有变量提升,那我们在他前面console应该拿到外层var定义的x才对。但是现在却报错了,说明执行器在if这个块里面其实是提前知道了下面有一个let申明的x的,所以说变量完全不提升是不准确的。只是提升后的行为跟var不一样,var是读到一个undefined,**而块级作用域的提升行为是会制造一个暂时性死区(temporal dead zone, TDZ)。**暂时性死区的现象就是在块级顶部到变量正式申明这块区域去访问这个变量的话,直接报错,这个是ES6规范规定的。

例2:

let myname= '极客时间'                             
{
  console.log(myname)

  let myname= '极客邦'                                                    
}

【最终打印结果】:VM6277:3 Uncaught ReferenceError: Cannot access 'myname' before initialization
【分析原因】:在块作用域内,let声明的变量被提升,但变量只是创建被提升,初始化并没有被提升,在初始化之前使用变量,就会形成一个暂时性死区。
【拓展】
var的创建和初始化被提升,赋值不会被提升。
let的创建被提升,初始化和赋值不会被提升。
function的创建、初始化和赋值均会被提升。

 

ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量 PI 之前使用它会报错。

注意要点

const 如何做到变量在声明初始化之后不允许改变的?其实 const 其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不允许改动。此时,你可能已经想到,简单类型和复合类型保存值的方式是不同的。是的,对于简单类型(数值 number、字符串 string 、布尔值 boolean),值就保存在变量指向的那个内存地址,因此 const 声明的简单类型变量等同于常量。而复杂类型(对象 object,数组 array,函数 function),变量指向的内存地址其实是保存了一个指向实际数据的指针,所以 const 只能保证指针是固定的,至于指针指向的数据结构变不变就无法控制了,所以使用 const 声明复杂类型对象时要慎重。

https://www.runoob.com/w3cnote/es6-let-const.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值