JavaScript变量提升的坑

本文深入探讨JavaScript中的变量提升,包括var、let和const的区别。var变量会在当前作用域顶部被提升,而let和const不会变量提升,存在暂时性死区。同时,介绍了词法作用域、函数提升和重复声明时函数优先的原则,强调了块级作用域和函数提升的理解对于避免编程陷阱的重要性。
摘要由CSDN通过智能技术生成

var ,未定义,let

  1. var
console.log(a)
var a = 10

结果:
在这里插入图片描述
原因:上面代码在编译阶段变成了下面代码,可以看到var a = 10在编译阶段变成了两句话,一句为声明变量:var a,一句为给变量赋值: a=10。而声明变量提升到了当前作用域(全局作用域)的最前面,赋值变量的语句留在原地。由于变量a在输出前只声明而未定义,所以会输出undefined,而不是报错,也不是输出10。

var a
console.log(a)
a = 10

  1. 未定义
console.log(a)
a = 10

结果:
在这里插入图片描述
原因:没有使用 var 关键字定义的全局变量没有预编译过程,所以如果把变量的使用放在定义之前则会报错

     如果声明变量时没有使用 var 关键字,则该变量一定为全局变量。到那时在调用的时候有以下区别:

  • 如果时声明在方法外的全局变量,在方法内可以直接使用;
  • 如果该全局变量时声明在方法内部的,则在方法外使用该变量时需要先调用方法,告知系统声明了全局变量才能使用。
    把 a 的顺序掉一下就可以运行正确
a = 10
console.log(a)

在这里插入图片描述

  1. let
console.log(a)
let a = 10

在这里插入图片描述
原因:let/const不会发生发生变量提升,在解析代码时,JavaScript引擎也会注意出现在块后面的let声明,只不过在此之前不饿能以任何方法来引用未声明的变量。在let声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛出ReferenceError错误。(JavaScript高级程序设计第四版P26)

要注意的是let与const不仅不会变量提升,而且还会把变量绑定到块作用域。例如

if(true){
  let a = 10;
}
console.log(a) //报错,形成块作用域

在这里插入图片描述
通过let声明的变量,不经没有变量提升,而且还形成了一个if{}块作用域。全局作用域访问不到a的值

词法作用域

var a = 10

function foo() {
  console.log(a)
}

foo(a) // foo运行在全局作用域 输出10

function foo2() {
  var a = 100
  foo() // foo运行在foo2包裹的作用域,输出10,并不会输出离自己近的100
}

foo2() 

在代码运行前(也就是编译阶段),作用域都已经确定好了。foo永远在全局作用域下,不管他在哪里运行,foo都会输出全局作用域下的a

函数提升

foo()

function foo() {
  console.log(1) //输出1,而不是报错
}

编译后

function foo() {
  console.log(1)
}

foo()

整个函数都会提升
但要注意的是下面这个例子

foo()

var foo = function() {
    console.log(1)//报错:Uncaught TypeError: foo is not a function
}

编译后

var foo
foo()
foo = function(){
console.log(1)
}

这一部分和变量提升的规则一样,可以看到由于将函数赋值给了一个变量,所以不会发生函数提升,而是发生变量提升。

重复声明/函数优先

foo()

function foo() {
  console.log(1) //输出1
}

var foo

这个例子中,变量foo被声明了两次,一次被声明为函数,一次被声明为未定义的变量。且这两次声明都是在全局作用域下,在同一个作用域下,变量名与函数名都相同的情况下(重复声明),会执行函数优先原则,忽略变量。
所以实际上编译的情况是这样的

function foo(){
    console.log(1)
}

// var foo  函数优先原则,这一句在编译的时候被注释

foo() // 输出1

小结

  • 编译阶段确定作用域并发生变量提升
  • 变量会发生变量提升,但变量的赋值会留在原地
  • let/const不会发生变量提升,而且还会形成块作用域
  • 重复声明下,遵循函数有优先原则

参考文章:https://juejin.cn/post/6987661731858219016

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值