Skip to content
快看这页儿写了啥...

简单阐述作用域、作用域链?

题干

  • 作用域

  • 作用域链

题解

简单来说,作用域是变量和函数可访问的范围,它定义了变量和函数的可见性和生命周期。作用域链是一个由嵌套的作用域组成的链表,用于在变量查找时确定变量的访问顺序和范围。

作用域(Scope)是指在程序中定义变量和函数的可访问范围。作用域规定了变量和函数在何处和何时可见,以及它们的生命周期。广义上的作用域有两种:

  • 词法作用域(静态作用域):词法作用域是在代码编写阶段就确定的作用域,它由代码中变量和函数的声明位置决定。在词法作用域中,变量和函数的访问权限是根据它们在源代码中的位置来确定的,与实际的运行时调用位置无关。
  • 动态作用域:动态作用域是一种根据函数的调用栈来确定变量访问权限的作用域规则。在动态作用域中,变量的可见性和生命周期是根据函数的实际调用位置来确定的,而不是根据代码中的声明位置。

注:JS 中没有动态作用域!,eval() & with 两个机制只是可以欺骗词法作用域。

JS 中基于词法作用域可以将作用域分为 3 种:

  • 全局作用域(Global Scope):全局作用域是在整个程序中都可访问的作用域。在全局作用域中定义的变量和函数可以在程序的任何地方被访问到。全局作用域在程序启动时创建,在程序结束时销毁。

  • 函数作用域(Function Scope):函数作用域是在函数内部定义的作用域。在函数作用域中定义的变量和函数只能在函数内部访问,外部作用域无法访问其中的变量和函数。每当调用函数时,都会创建一个新的函数作用域。函数作用域在函数执行结束后被销毁。

  • 块级作用域(Block Scope):块级作用域是在代码块(如 if 语句、for 循环、函数等)内部定义的作用域。在 ES6 之前, JS 只有全局作用域和函数作用域,没有块级作用域。但是通过使用 letconst 关键字,我们可以在块级作用域中定义变量,并且这些变量只在当前块内有效。

作用域链(Scope Chain)是一个由嵌套的作用域组成的链表,用于在变量查找时确定变量的访问顺序和范围。当在某个作用域中引用一个变量时,JS 会先在当前作用域中查找变量,如果找不到,就会沿着作用域链向上一级作用域查找,直到找到该变量或到达全局作用域。这种嵌套的作用域链关系使得内部作用域可以访问外部作用域中的变量,但外部作用域无法访问内部作用域中的变量。

作用域链的形成是由函数的定义位置决定的,而不是函数的调用位置(词法作用域)。当函数被定义时,它会记住自己被定义时的作用域链,无论在何处调用该函数,它都可以访问到定义时的作用域链。

相关

eval 是做什么的、使用场景

贡献者

isboyjc's avatar isboyjc

浏览量(PV)  次  ·  独立访客(UV)  人次
不正经的前端 | 八股 · 欢迎 star ⭐