JS的作用域和作用域链

 

作用域

定义

作用域是指在程序中定义变量的区域,该位置决定了变量的生命周期。通俗地理解,作用域就是变量与函数的可访问范围,即作用域控制着变量和函数的可见性和生命周期。

⚠️:作用域是由代码中函数声明的位置来决定的,跟在哪里调用无关

用途

作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。

类别

  • 全局作用域
  1. 最外层函数 和在最外层函数外面定义的变量拥有全局作用域
  2. 所有末定义直接赋值的变量自动声明为拥有全局作用域
  3. 所有 window 对象的属性拥有全局作用域
  • 函数作用域

在函数内部定义的变量或者函数,并且定义的变量或者函数只能在函数内部被访问。函数执行结束之后,函数内部定义的变量会被销毁。

  • 块级作用域(ES6新增)

ES6 引入了 let 和 const 关键字,从而使 JavaScript 也能像其他语言一样拥有了块级作用域。

作用域链

定义

简单来说就是由作用域组成的链条。例如在函数里面有个a变量,函数内部不存在,则会找他的父级作用域,直到找到或者在全局作用域还没找到则放弃。(在ES5之后是通过变量环境里的outer即外部环境来实现的)

用途

通过作用域来找变量(查找变量的机制)。注意⚠️:内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境的任何变量和函数。

作用域与执行上下文

许多开发人员经常混淆作用域和执行上下文的概念,误认为它们是相同的概念,但事实并非如此。

我们知道 JavaScript 属于解释型语言,JavaScript 的执行分为:解释和执行两个阶段,这两个阶段所做的事并不一样。

解释阶段

  • 词法分析
  • 语法分析
  • 作用域规则确定

执行阶段

  • 创建执行上下文
  • 执行函数代码
  • 垃圾回收

JavaScript 解释阶段便会确定作用域规则,因此作用域在函数定义时就已经确定了,而不是在函数调用时确定,但是执行上下文是函数执行之前创建的。执行上下文最明显的就是 this 的指向是执行时确定的。而作用域访问的变量是编写代码的结构确定的。

其实大家看下作用域和执行上下文各自的职责,你会发现他们几乎是没有啥交集的。那么为啥通常两者会被同时提到呢?因为在一个函数被执行时,创建的执行上下文对象除了保存了些代码执行的信息,还会把当前的作用域保存在执行上下文中。所以它们的关系只是存储关系。

参考

https://www.cnblogs.com/fundebug/p/10535230.html

极客时间浏览器原理与实践

https://www.jianshu.com/p/cc79f22b99fe

 

 

 

原文地址:https://www.cnblogs.com/suihang/p/13395225.html