上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

JavaScript中你所不知道的"变量提升"

[复制链接]
  • TA的每日心情
    开心
    2025-7-8 11:40
  • 签到天数: 53 天

    [LV.5]常住居民I

    149

    主题

    48

    回帖

    456

    积分

    高级工程师

    积分
    456
    发表于 2025-11-11 16:18:46 | 显示全部楼层 | 阅读模式

    我们所知的"变量提升"
    ☆经典案例与吐槽
    这是每一个js的初学者都接触过的经典案例:

    //我们眼中的代码
    
    console.log(a); //输出为undefinedvar 
    a=1;

    先打印,后执行?!
    居然没有报错!!Σ(゚д゚;)
    这反直觉的语言究竟是谁设计的!!!("▔□▔)/
    ☆出现了!是“变量提升”!太好了,我们有救了!
    网课的老师或是教科书会告诉我们,这是因为发生了“变量提升”,变量的声明被提高到当前作用域的顶部了。实际的代码执行逻辑如下:

    //实际上的代码执行逻辑
    
    var a;
    console.log(a);
    a=1;

    于是我们便骂骂咧咧的接受了这个概念,并在脑海里为它添加上一个名为“特殊情况,特殊处理”的标签。
    但是,真的这样就好了么?这与在米共代码里写上一万个if分支有什么区别!这是对主包脑容量可耻的浪费!
    ☆反叛的号角已然吹响!
    这是一个仅靠“变量提升”的思维所解决不了的例子:

    //我们眼中的代码
    
    console.log(a);//输出为函数 a()
    var a = 1;
    function a() { };

    按照“变量提升”的思维,代码的执行逻辑如下

    //“变量提升”思维下,代码执行的逻辑
    
    var a;console.log(a);//输出为 undefined
    a=1;
    function a(){};

    这是经典的错误,标准的零分!

    要解决这个疑问,同学们需要知道究竟是怎样的机制存在,才能知道“变量提升”在这里不管用的原因。
    我们所不知的背后机制
    ☆JaveScript的预编译机制
    众所周知,在js代码解释执行前,需要先对代码进行预编译。而js特殊的预编译机制就是导致“变量提升”现象出现的原因。
    ☆全局预编译
    全局预编译的三个步骤
    1.创建全局执行上下文 GO对象(Global Object)
    2.在全局作用域中寻找声明对象的段落,以键值对{对象名:undefined}的形式添加进GO对象中。
    3.在全局作用域中寻找声明函数的段落,以键值对{函数名:函数体}的形式也添加进GO对象中
    在完成以上三个步骤之后才开始解释执行js代码,执行时在全局作用域下调用函数与变量时以GO对象中对应的值为准。
    示例:

    //原来的代码
    
    console.log(a);
    console.log(b);
    var a;function b(){};
    

    经过预编译后的代码逻辑:

    // 事实上的代码逻辑
    
    GO = {    
    a: undefined, 
    b: function () { }
    }
    console.log(GO.a);
    console.log(GO.b);
    

    同理对上一部分疑问的解答:

    //我们眼中的js代码
    
    console.log(a);
    var a = 1;
    function a() { };
    
    //实际上的执行逻辑:
    
    GO=
    {    
    a:function (){},   
    //函数a加入GO时,函数名与对象名相同,所以将属性名a对应的属性值修改了。
    }
    console.log(GO.a)//输出为函数 a()

    于是我们用全局预编译的过程,成功解释了“变量提升”现象发生的原因,以及该说法的局限性。(=・ω・=)
    新人报道
    ☆关于文章
    本文仅适用于新手,更多是用来记录与分享up的学习历程,如果对初入js编程您很有所帮助,不放给up点上一个小小的赞啦(°▽°)八(°▽°)♪
    ☆关于文章可能存在的错误与不严谨处
    还望大佬轻喷,如若您在百忙之中指出错误之处,up( ´(00)ˋ )顶礼膜拜
    ☆本文对js预编译的过程仅作部分阐述,欲知全貌如何,且听下回分解

    ☆关于up
    是学生,前端在学,初学者,初踏入前端界(;¬_¬)
    最后 合理利用自己每一分每一秒的时间来学习提升自己,不要再用 “没有时间” 来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代! 这里有内 u 测职位通道哦https://jsj.top/f/o38ijj!

    作者:soda_yo
    来源:稀土掘金

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表