乐趣区

JavaScript词法作用域

在开始之前,我们先来看一段代码:

var name = 'window';

function display() {alert(name);
    
    var name = 'local';
    
    alert(name);
}

display();

请不要去运行代码,根据你掌握的 js 知识来给出你的答案,我相信会有很多童鞋会说这很简单啊,不就是 window 和 local 吗?!然而事实真的是这样吗?

作用域

要理解词法作用域,首先要明白什么是作用域。作用域是变量和函数的可访问范围,控制着变量和函数的可见性及什么周期。一般来说 js 中的作用域可以分为全局作用域和局部作用域(es6 还有块级作用域)。而 JavaScript 的词法作用域采用的是 静态作用域

  • 静态作用域:指词法作用域在词法分析阶段就已经确定了,不会改变,可以简单理解为取决于源代码。
  • 动态作用域:会根据程序的调用、执行而改变,取决于在什么地方被调用。

词法作用域

一个文档流中的 JavaScript 代码的执行顺序大概分为以下几个步骤:

1、读入第一个代码片段(js 引擎不是一行一行的分析代码,而是一段一段的分析执行)。

2、进行词法分析,检查语法是否有错误(比如是否少了括号 …),如果有错误则抛出错误。

3、对 var 定义的变量和 function 关键字定义的函数进行‘与解析’,也就是我们常说“变量提升”。

4、执行代码段,如果发生错误,跑出错误异常。

5、如果还有下一段代码,则继续读入下一段代码,并且重复第 2 步。

6、结束。

附一张图:

我们来分析开篇的代码:

调用 display 函数的时候,读入代码片段,进入第二步进行词法分析,未发现错误,然后进行第三部,进行与解析,即变量提示,将变量 name 提升到函数的第一行,此时只有 var name,并未进行赋值,因此第一个 alert 的值是 undefined;继续执行 nam =‘local’;因此第二 alert 的值为 local。所以正确答案是 undefined 和 local。

退出移动版