全国旗舰校区

不同学习城市 同样授课品质

北京

深圳

上海

广州

郑州

大连

武汉

成都

西安

杭州

青岛

重庆

长沙

哈尔滨

南京

太原

沈阳

合肥

贵阳

济南

下一个校区
就在你家门口
+
当前位置:首页  >  技术干货

深度解析Javascript中的变量提升

发布时间:2022-06-02 14:12:00
发布人:wjy

> 大家好,我是前端老陈醋,有关js中的变量提升,很多小伙伴可能都会有疑问,尤其是面试的过程中有大量有关于变量提升相关的题,那么浏览器在解析js的过程中,js中的变量究竟是怎么提升的呢?想要彻底解决这些问题,就要理解浏览器是怎么解析js代码的,那么我们今天就来深度解析一下这个问题哈。

深度解析Javascript中的变量提升

## 首先在JS中涉及两种作用域的问题,那么什么是作用域呢?

> 作用域是代码中所使用名字的作用范围,分为Script全局作用域和函数局部作用域。 当浏览器在解析网页内容时,会分别启动不同的解析器来解释代码的含义,如解析标签(超文本)的解析器、解析CSS样式的解析器,解析javascript脚本的解析器。且解析过程为同步(按顺序)解析。所以当浏览器解析到script标签时,会停止对html和css的解析,同时启动javascript的解析器。而在解析javascript的过程中我们主要关注解析器中的两个步骤:

1. 预解析,即在当前作用范围中去寻找var、function、形参这三个内容。

- 如果找到var关键字、则提取var后面的名字放到当前作用域中,且默认给这个变量初始化一个值为undefined。
- 如果找到function关键字,则提取函数名放到当前作用域中,且将整个函数块赋值给函数名。
- 如果找到形参,则将形参名放到当前作用域中,且默认初始化为undefined。这个过程也称为变量提升。

\2. 逐行解读代码(即从上到下依次执行每一条语句)且分为两个步骤:

- 执行表达式
- 函数调用。

```js
/*
        一、预解析(寻找var function 形参)
            i = undefined (进入script作用域时,找到var)
            fn = function fn(){alert(2);}  (进入script作用域时,找到function)
        二、逐行解读代码(函数声明,直接跳过)
            1. 执行表达式
            2. 函数调用
    */
    alert(i); //1. 当执行第一个表达式时,输出i的值为undefined
    //第一个找到的是var,所以将i放到预解析中,初始化为undefined
    var i = 1; //2. 当执行第二个表达式i = 1时,会在预解析中先找到变量i,将值修改为1
    alert(i);//3. 当执行输出表达式时,在预解析中i的值 1 输出
    function fn(){ //4. 函数声明,不执行,直接跳过
        alert(2);
    }
    alert(i); //5. 当执行输出表达式时,在预解析中i的值 1输出
```

> 当变量名与函数名相同时:

```js
/*
        一、预解析(寻找var function 形参)
            a = undefined  (在作用域中第一次找到var a) (在找到同名的函数a时,当前变量a被丢弃)
            a = function a(){alert(2);}   (在作用域中第二次找到 function a,所以在作用域同时出现一个变量a和一个函数a,此时,将变量a丢弃,保留函数a) (在找到下一个function a时,此时的函数 a 被覆盖)
            a = function a(){alert(4);}   (在作用域中第三次找到function a时,与前面是相同的函数 a,会将前面的函数a 进行覆盖)
            a = 1   (当执行到a = 1时,上面的a = function a(){alert(4);} 将被覆盖成 1)
        二、逐行解读代码(函数声明,直接跳过)
            1. 执行表达式
            2. 函数调用
    */
    alert(a);  // 1. 在执行该表达式时,预解析中只有 a = function a(){alert(4);} 所以此时的结果为   function a(){alert(4);}
    var a = 1;  // 第一次找到的 var a
    alert(a); //2. 在执行该表达式时,预解析中的 a 值为 1 ,所以结果为  1
    function a(){ //第二次找到的 a
        alert(2);
    }
    function a(){  //第三次找到的  a
        alert(4);
    }
    alert(a);  // 3. 在执行该表达式时,预解析中的 a 值为 1 ,所以结果为  1
```

> 当有多个script标签时: - 多个script标签时,从上到下依次解析script作用域,所以建议将所有声明的语句放到第一个script中。

```html
<script>
        /*
            一、预解析(寻找var function 形参)
                fn = function(){alert(2);} (在解析第一个script时,只找到一个funciton fn);

                a = 1  (在解析第二个script作用域时,找到 var a)
            二、逐行解读代码(函数声明,直接跳过)
                1. 执行表达式
                2. 函数调用
        */
        alert(a); //报错,在执行该表达式时,因为在预解析中没有a变量,所以此时会报错。
        function fn(){
            alert(2);
        }
    </script>
    <script>
        var a = 1;
        fn(); //2   在调用该函数时,在预解析中已经存在function fn,所以输出函数中的表达式 值为2
    </script>
```

更多关于“web前端培训”的问题,欢迎咨询千锋教育在线名师。千锋已有十余年的培训经验,课程大纲更科学更专业,有针对零基础的就业班,有针对想提升技术的提升班,高品质课程助理你实现梦想。

相关文章

抖音小店怎么换绑定的手机号

抖音小店怎么换绑定的手机号

2023-10-08
企业号可以开通抖音小店吗

企业号可以开通抖音小店吗

2023-10-08
抖音小店怎样绑定多个店铺账号

抖音小店怎样绑定多个店铺账号

2023-10-08
抖音小店运营做什么的

抖音小店运营做什么的

2023-10-08

最新文章

上海物联网培训一般费用多少

上海物联网培训一般费用多少

2023-09-12
北京物联网培训费用大概多少

北京物联网培训费用大概多少

2023-09-12
北京物联网培训需要费用高不高

北京物联网培训需要费用高不高

2023-09-12
上海效果好的物联网培训费用高吗

上海效果好的物联网培训费用高吗

2023-09-12
在线咨询 免费试学 教程领取