JavaScript 变量提升是什么?


prtyaa
prtyaa 2023-12-26 17:54:51 65212
分类专栏: 资讯
  • JavaScript 众多特性之一就是所谓的变量提升。

    现在,如果你是 JavaScript 编码的新手,很可能还没有熟练地编写代码。因此, 对于变量提升可能也不熟悉。

    变量提升到底是什么?

    当 JavaScript 编译所有代码时,所有使用 var 的变量声明都被提升到它们的函数/局部作用域的顶部(如果在函数内部声明的话),或者提升到它们的全局作用域的顶部(如果在函数外部声明的话),而不管实际的声明是在哪里进行的。这就是我们所说的“提升”。请记住,这种“提升”实际上并不发生在你的代码中,而只是一种比喻,与JavaScript编译器如何读取你的代码有关。记住当我们想到“提升”的时候,我们可以想象任何被提升的东西都会被移动到顶部,但是实际上你的代码并不会被修改。

    函数声明也会被提升,但是被提升到了最顶端,所以将位于所有变量声明之上。

    在编译阶段变量和函数声明会被放入内存中,但是你在代码中编写它们的位置会保持不变。

    说得够多了,给大家看一些代码的简单例子,来演示提升的影响。

    第一个例子

    如果我们在全局作用域编写以下代码:

    console.log(myName);
    var myName = 'rainyjune';
    

    你认为输出结果是什么?

    • Uncaught ReferenceError: myName is not defined
    • rainyjune
    • undefined

    第三个才是正确答案。

    正如我们前面提到的,当你的 JavaScript 代码在运行时,变量会移动到它们的作用域的顶部。然而,需要注意的一个关键点是,唯一移动到顶部的是变量声明,而不是赋值给变量的实际值。

    我们以前面的代码为例,看看 JavaScript 编译器在运行时是如何执行代码的:

    var myName;
    console.log(myName);
    myName = 'rainyjune';
    

    这就是为什么 console.log 输出“undefined”,因为它检测到变量 myName 存在,但是 myName 直到第三行才被赋予一个值。

    另一个例子

    function hey() {
    console.log('hey ' + myName);
    };
    hey();
    var myName = 'rainyjune';
    

    这里调用 hey() 函数仍然返回 undefined,因为实际上 JavaScript 编译器会在执行时这样执行:

    function hey() {
    console.log('hey ' + myName);
    };
    var myName;
    hey();
    myName = 'rainyjune';
    

    所以当函数被调用时,它知道有一个变量叫做 myName,但是这个变量没有被赋予值。

    函数声明的例子

    catName("Chloe");
    function catName(name) {
    console.log("My cat's name is " + name);
    }
    /*
    The result of the code above is: "My cat's name is Chloe"
    */
    

    上述代码中,虽然我们在编写函数之前先调用了它,代码还是正确执行了。这是因为函数声明发生了提升。

    只有声明被提升

    JavaScript 只提升声明,而不提升初始化。如果一个变量在访问之后再声明和初始化,那么此刻它的值是 undefined。例如:

    console.log(num); // 返回 undefined,因为只有声明被提升,此阶段还没有初始化
    var num; // 声明
    num = 6; // 初始化
    

    下面是一个只初始化的例子。这样不会发生提升,所以访问变量会抛出 ReferenceError 异常。

    console.log(num); // 抛出 ReferenceError 异常
    num = 6; // 初始化
    

    let 和 const 会发生提升吗?

    在ECMAScript 2015中,let 和 const 声明的变量会发生提升,但在变量声明之前引用这个变量会导致一个 ReferenceError,因为从代码块开始到变量声明被处理期间,这个变量都处于一个“时间死区”。

    console.log(x); // ReferenceError
    let x = 3;

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=30949
赞同 0
评论 0 条
prtyaaL0
粉丝 1 发表 2554 + 关注 私信
上周热门
银河麒麟添加网络打印机时,出现“client-error-not-possible”错误提示  1448
银河麒麟打印带有图像的文档时出错  1365
银河麒麟添加打印机时,出现“server-error-internal-error”  1151
统信桌面专业版【如何查询系统安装时间】  1073
统信操作系统各版本介绍  1070
统信桌面专业版【全盘安装UOS系统】介绍  1028
麒麟系统也能完整体验微信啦!  984
统信【启动盘制作工具】使用介绍  627
统信桌面专业版【一个U盘做多个系统启动盘】的方法  575
信刻全自动档案蓝光光盘检测一体机  484
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

添加我为好友,拉您入交流群!

请使用微信扫一扫!