[JavaScript]作用域相关的总结

429 阅读3分钟

一、作用域的定义

作用域指程序源代码中定义变量的区域,规定了如何查找变量即确定当前执行代码对变量的访问权限

JavaScript采用的是词法作用域:也就是函数的作用域函数定义的时候就决定了(重要!javaScript代码的运行会经过准备(包含变量初始化、函数定义等)执行(逻辑)两个阶段)

与词法作用域相反的是动态作用域,也就是函数的作用域是在函数调用的时候才决定,这里仅供了解就好

二、作用域的类别

在JavaScript中主要有全局作用域函数作用域块级作用域(ES6之前没有)三个

  • 全局作用域:顾名思义,是为最顶层最大的范围
  • 函数作用域:仅在某个函数内部有效的范围
  • 块级作用域:仅在某个块级代码内部有效的范围
var globalValue = 'Global' //约定在全局作用域内,在该范围内的事物都可以访问到

function fn () {
    var fnValue = 'fn' //约定在函数作用域内,只有在该函数内的事物才可以访问到
}
{
    let blockValue = 'blockValue' //约定在块级作用域内,只有在该块级内的事物才可以访问到
}

三、作用域的作用与作用域链

作用域是一个很抽象的概念,可以理解成一个地盘,具有

  • 独立性:作用域包裹起来让变量不会外泄,所以在不同作用域下同名变量不会有冲突即变量隔离
  • 分层与嵌套:作用域是有层级关系的,上下级关系的确定就看函数是在哪个作用域下定义的(在哪个作用域下定义就是哪个作用域的子作用域

内层作用域(子作用域)可以访问外层作用域(父作用域)的变量,反之则不行。在查找一个变量时,如果在本作用域内无定义,那么就会往上一层父作用域查找,一层一层向上直到全局作用域,这个过程的路径链便为作用域链

四、作用域的创建

举个例子加深一下理解作用域和作用域链

var a = 1

function foo() {
    var b = 2
    function bar(c) {
        var d = 3
        console.log(a, b, c, d)
    }
    bar(b * 3)
}

function kk() {
    var e = 4
    console.log(a, e)
}

1.假设这段代码处在代码最外层-全局,作用域层级为

[全局作用域]

2.在全局作用域内定义foo函数,会有一个foo作用域产生

[全局作用域[foo作用域]]

3.然后走进foo里面,在foo作用域内定义bar函数,会有一个bar作用域产生

[全局作用域 [foo作用域 [ bar作用域 ] ] ]

4.出来后,在全局作用域内定义了kk函数,会有一个kk作用域产生

[全局作用域 [foo作用域 [ bar作用域 ], kk作用域]]

五、总结

作用域是执行上下文知识的前置知识,作用域的初始化是其中一个重要的步骤

整个流程看下来其实作用域也没那么难,基础理解好了,再使用起来就会清晰很多