js作用域的相关知识

  众所周知,在ES6之前,JavaScript是没有块级作用域的,如下图所示:

js作用域的相关知识

  学过其他语言的同学肯定有点诧异,为什么会这样呢?因为js还是不同于其他语言的,在ES5中,只有全局作用域和函数作用域,并没有块作用域,当然我们可以实现块作用域的功能。看下面代码:

js作用域的相关知识

  在这段段代码中,我们使用立即执行函数(IIFE)创建了一个局部函数来模仿块级作用域。在ES5时代,JavaScript的作用域只有用全局作用域和局部作用域的说法。到了ES6时代,块级作用域的登场。

  一、关于ES5时代     1.变量提升

      说到js的变量提升,就不得不说一下js的词法分析。总所周知js代码自上而下执行,但是在js代码执行前,会先进行词法分析。所以js运行要分为词法分析程序执行两个阶段。

      js词法分析主要分为3个步骤:

        1.分析形参:如果函数有形参,则给当前活动对象增加形参属性,默认为undefined。

        2.分析变量声明:如果有类似var a  之类的声明,若没有该属性则增加属性,若已存在则不做操作。默认为undefined。变量的赋值在执行阶段才进行,即执行到该变量的时候才有 a = 11。

        3.分析函数声明:类似 function a(){},若当前活动对象没有该属性则新增否则重写该属性为方法a。

      如图所示,在这段代码中,按照一般的逻辑,第一个console.log会报错为“a is not defined”。

js作用域的相关知识

      但是事实上,根据js词法分析的第二步,var a这个声明会被提前到代码的顶部。但是a=1这个赋值却不会,所以这段函数正确的步骤为:

js作用域的相关知识

      这就是所谓的变量提升。

    2.函数提升

      在js中,我们常见的常见函数的创建方式有三种——函数构造式(不推荐使用,此处不做分析),函数声明式和函数表达式。下面第一行的代码为函数声明式,第二个为函数表达式。

      

1 function fn1(){} 2 var fn2=function(){};

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyyzs.html