Javascript基础(二)之词法作用域

65 阅读2分钟

词法作用域:

  • 词法作用域就是指作用域是由代码中函数声明的位置来决定的
  • 词法作用域是静态的作用域,通过它就能够预测代码在执行过程中如何查找标识符。
  • 内部函数总是可以访问它们的外部函数中的变量

代码如下:

    function foo() {
        var myName = '1'
        bar()
    }
    function bar () {
        console.log(myName)
    }
    var myName = '2'
    foo()

分析上述代码:

全局作用域
    编译阶段
           执行上下文的变量环境
                    function foo () {...}
                    function bar () {...}
                    myName = undefined
           可执行代码
                    myName = '2'
                    foo()
   执行阶段, 执行maName = '2' 和 foo()
foo函数作用域
    编译阶段
           执行上下文的变量环境
                    myName = undefined
           可执行代码
                    myName = '1'
                    bar()
   执行阶段, 执行myName = '1' 和 bar()
bar函数作用域
    编译阶段
           执行上下文的变量环境
                    无
           可执行代码
                    console.log(myName)
   执行阶段, console.log(myName)

调用栈图示如下 

outer:每个执行上下文的变量环境中,都包含了一个外部引用,用来指向外部的执行上下文

image.png

  1. 当JS执行全局代码的时候会先编译全局代码并创建执行上下文
  2. 全局代码编译完成,执行赋值操作 myName = 2
  3. 执行foo(), foo函数符合‘一段代码’, 需要先被编译,编译完成后执行
  4. foo函数编译完成,执行赋值操作 muName = 1
  5. 执行bar(), bar函数符合‘一段代码’, 需要先被编译,编译完成后执行
  6. 执行到console.log(myName)的时候, 在bar的词法环境和变量环境均未查找到myName, 便去outer指向的作用域去查找
  7. 此时outer指向于 全局作用域(bar函数在全局作用域的执行上下文的变量环境中被定义)
  8. 在全局可执行上下文中的变量环境中找到maName并打印2

如果把代码改一下,下面的代码就会打印1,原理同上

    function foo() {
        var myName = '1'
        bar()
        function bar () {
            console.log(myName)
        }
    }
    var myName = '2'
    foo()

原文链接:blog.csdn.net/qq_44767749…