Javascript高级编程学习笔记(10)—— 作用域、作用域链

时间:2023-03-08 22:25:48

昨天介绍了,JS中函数的作用域

什么词法环境之类的,可能很多小伙伴不太明白。

在今天的内容开始之前,先做个简短的声明:

词法环境这一概念是在ES5中提出的,因为词法环境主要用于保存let、const声明的变量、函数

而在ES3中对变量相关的信息都保存在变量对象上;

从功能上来说变量对象可以看作是词法环境中的环境记录

两者从功能上来说区别不大,只是不同版本的ES有不同的说法

为了保持与前文的一致,这篇文章中我还是用环境记录来描述JS保存当前执行环境(上下文)中定义的变量和函数的对象

ES6之前JS中的作用域只有全局作用域和局部作用域(函数作用域)两种,后文将基于此进行解释

作用域

作用域联系前文我们可以理解为执行环境(上下文)中的词法环境

而每个作用域都由一个保存变量的对象(环境记录)和一个指向外部词法环境的outer(对外部环境引用)构成

作用域之间的嵌套关系由outer来维护

一个个作用域通过outer形成的链式结构就被称作作用域链

在《js高级程序设计》中把执行栈顶端的执行环境(上下文)中的作用域(词法环境)称为活动对象

作用域链

那么作用域链是干嘛的呢?

作用域链就是让我们能在子作用域中访问父作用域链中的变量的

在解释作用域的时候我提过,每个作用域都包含了一个对外部作用域的引用,这个引用是单向的

这也是子作用域能访问父作用域,而父作用域不能访问子作用域的原因

Javascript高级编程学习笔记(10)——  作用域、作用域链

当我们在使用变量的时候,JS会解析标识符,解析实际上就是一个沿着作用域链一层层搜索标识符的过程

在搜索标识符这一过程中,只要搜索到符合的标识符就会立即停止搜索

这也就是当父级作用域和子作用域有同名变量时,JS以子作用域中的为准的原因Javascript高级编程学习笔记(10)——  作用域、作用域链

延长作用域链

在JS中除了函数之外,还有一些语句也会产生作用域,从而延长作用域

1.try-catch中的catch会产生一个新的作用域

2.with语句 会将指定对象作为作用域添加到执行栈的顶端

在使用上方的语句时需要注意一下

PS . IE8 之前的JS版本中catch会将错误对象添加到当前的执行环境的变量对象中,而不是新建一个,IE9中修复了该bug

没有块级作用域

在ES6之前JS是没有块级作用域的,也就是大括号之间的代码块不会产生一个独立的作用域

也就是说花括号中间声明的变量会添加到当前的执行环境中

这也是for循环中声明的 i 在外部也能访问的原因

最近的文章可能都没有什么例子的配合了,一是有些东西实在不好举例,二是自己水平有限

望谅解,JS中的闭包等问题会在后面介绍object里面的function类型的时候介绍