首页 > 编程语言 >JavaScript的变量提升

JavaScript的变量提升

时间:2023-08-27 11:22:06浏览次数:40  
标签:console log JavaScript let 提升 var main 变量

参考资料:https://time.geekbang.org/column/article/126339

目录

变量提升是在代码执行时,把变量和函数的声明部分提升到代码开头的行为,变量被提升后,会被默认设置为undefined

变量提升

当使用var关键字声明变量时,

consolt.log(a)
var a = 1
// undefined

等价于

var a
console.log(a)
a = 1

变量a作为全局变量时,其声明会被提升到全局作用域的顶端,而初始化和赋值不会。

在函数作用域中

function main() {
    console.log(a)
    var a = 1
}

main()
// undefined

函数内部变量的声明会被提升到函数作用域的顶端,等价于

function main() {
    var a
    console.log(a)
    a = 1
}

main()

变量形式声明的函数

JavaScript中函数的声明有两种形式

function main() {
    // 函数形式声明
}

var func = main() {
    // 变量形式声明
}

在使用变量形式声明函数时,也会出现提升的现象。

func()

var func = function () {
    console.log("Hello World!\n")
}
// TypeError: func is not a function

func1()
function func1() {
    console.log("Hello World!\n")
}
// Hello World!

变量提升导致的问题

变量被覆盖

var s = "HTML"
function main() {
    console.log(s);
    if (0) {
        var s = "CSS"
    }
}

main()
// undefined

当执行到console.log(s)时,会在执行上下文中寻找变量s,一个在全局上下文中HTML,另一个在函数main的执行上下文中CSS

JavaScirpt会优先从当前的执行上下文(函数的执行上下文)中查找变量,由于变量提升的存在,包含了s = undefined

变量不被销毁

function main() {
    for (var i = 0; i < 6; ++i) {

    }
    console.log(i)
}

main()
// 6

避开变量提升

引入letconst关键字

ECMAScript6已经通过引入块级作用域和let, const关键字避开这种设计缺陷。

console.log(a)
let a = 1
// ReferenceError: Cannot access 'a' before initialization
function main() {
    let a = 1
    if (1) {
        let a = 2
        console.log(a)
    }
    console.log(a)
}

main()
// 2 1

let关键字支持块级作用域,作用块内的变量不影响外面的变量。

块级作用域

function main() {
    var a = 1
    let b = 2
    {
        let b = 3
        var c = 4
        let d = 5
        console.log(a)
        console.log(b)
        console.log(d)
    }
    console.log(b)
    console.log(c)
}

main()
//  1 3 5 2 4

在执行代码前,JavaScript会先编译并创建执行上下文

  • var声明的变量,会被存到变量环境
  • let声明的变量,会被存到词法环境
  • 函数内部let声明的变量不会存到词法环境

执行到main函数时,变量环境中a = 1,词法环境中b = 2,内部的块作用域中用let声明的变量,存到词法环境中的单独区域。

在词法环境中,维护一个栈结构,栈底是最外层变量,进入一个作用域后,把内部的变量压到栈顶,执行完后在出栈。

执行到console.log()时,从词法环境的栈顶向下查找,如果没有找到,继续在变量环境中查找:

块作用域执行结束后,内部变量的定义出栈,继续向下执行其余代码。

标签:console,log,JavaScript,let,提升,var,main,变量
From: https://www.cnblogs.com/euler0525/p/17660020.html

相关文章

  • 【机器学习 | 数据预处理】 提升模型性能,优化特征表达:数据标准化和归一化的数值处理技
    ......
  • JavaScript中的不可变原始值和可变对象引用
    在JavaScript中,原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)之间存在着根本的区别。原始值是不可变的,意味着它们的值无法改变。这对于数字和布尔值很容易理解:修改它们的值是没有意义的。然而,对于字符串来说,这可能会稍微不太直观。由于字符串类似于字符数组,可......
  • JavaScript中实现类与类继承
    new操作符调用的作用如果一个函数被使用new操作符调用了,那么它会执行如下操作:1.在内存中创建一个新的对象(空对象);2.这个对象内部的[[prototype]]属性会被赋值为该构造函数的prototype属性;(后面详细讲);3.构造函数内部的this,会指向创建出来的新对象;4·执行函数的内部代码(函数体代码);5·......
  • 初识JavaScript
    1995年,JavaScript问世。当时,它的主要用途是代替Perl等服务器端语言处理输入验证。在此之前,要验证某个必填字段是否已填写,或者某个输入的值是否有效,需要与服务器的一次往返通信。网景公司希望通过在其Navigator浏览器中加入JavaScript来改变这个局面。在那个普遍通过电话......
  • javascript学习日记day6
    前两天跑去学公司的框架和游戏脚本去了,果然我就是属于三天打鱼两天晒网的那种,下面是今天的笔记对象的增删改查letgood={goods:'小米',name:'小米10青春版',num:100012816024,weight:'0.55kg',address:'中国大陆'}增:good.pric......
  • 用 PHP 和 JavaScript 显示地球卫星照片
    向日葵8号气象卫星是日本宇宙航空研究开发机构设计制造的向日葵系列卫星之一,重约3500公斤,设计寿命15年以上。该卫星于2014年10月7日由H2A火箭搭载发射成功,主要用于监测暴雨云团、台风动向以及持续喷发活动的火山等防灾领域。——百度百科日本发射这颗卫星后,不仅......
  • 两种不同的方法来检查Python中的变量是否是字符串
    在Python中,每个变量都有一个数据类型。数据类型表示一个变量内部存储的是哪种数据。数据类型是编程语言最重要的特征,它区分了我们可以存储的不同类型的数据,如字符串、int和float。在处理许多编程问题时,可能会遇到这样的情况:我们需要找到某个变量的数据类型来对其执行一些任务。......
  • SQLite 3.43 发布,JSON 处理性能提升 2 倍
    SQLite3.43发布,JSON处理性能提升2倍来源:OSCHINA编辑: 局2023-08-2516:58:59 38月26日「源创会」北京站,聊聊AI大模型与底层技术>>> SQLite3.43已正式发布。SQLite是一个C语言库,实现了一个小型、快速、独立、高可靠性、全功能的SQL数据库......
  • JavaScript-算术运算符
    概述JavaScript共提供10个算术运算符,用来完成基本的算术运算。加法运算符:x+y减法运算符: x-y乘法运算符: x*y除法运算符:x/y指数运算符:x**y余数运算符:x%y自增运算符:++x 或者 x++自减运算符:--x 或者 x--数值运算符: +x负数值运算符:-x减法、乘法、除法运算法比较单纯......
  • 记一次提升性能的写法和技巧
    1.使用异步编程:使用异步方法可以提高应用程序的响应性能,特别是在处理I/O密集型操作时。通过使用async和await关键字,可以将长时间运行的操作放在后台线程上,从而释放主线程并提高应用程序的吞吐量, Channel通道,进程内队列(Queue)。2.使用内存池:在.NETCore中,可以使用MemoryPo......