Debugger.Environment

Debugger.Environment 实例表示一个词法环境,将名称与变量关联起来。每个表示调试目标帧的 Debugger.Frame 实例都具有一个关联的环境对象,描述该帧范围内有效的变量;每个表示调试目标函数的 Debugger.Object 实例都具有一个环境对象,表示该函数闭包的环境。

ECMAScript 环境形成一个树,其中每个局部环境都由其封闭环境(在 ECMAScript 术语中,其“外部”环境)作为父级。我们说一个环境绑定一个标识符,如果该环境本身将标识符与一个变量关联,独立于其外部环境。我们说一个标识符在一个环境中有效,如果该标识符在该环境或任何封闭环境中被绑定。

当调试器检查堆栈帧和函数对象时,SpiderMonkey 会根据需要创建 Debugger.Environment 实例;将 Debugger.Environment 作为函数或构造函数调用会引发 TypeError 异常。

SpiderMonkey 为其通过给定的 Debugger 实例呈现的每个环境只创建一个 Debugger.Environment 实例:如果调试器通过两种不同的方式遇到相同的环境(也许两个函数闭包了相同的环境),SpiderMonkey 每次都会向调试器呈现相同的 Debugger.Environment 实例。这意味着调试器可以使用 == 运算符识别两个 Debugger.Environment 实例何时引用调试目标中的相同环境,并在 Debugger.Environment 实例上放置自己的属性以存储有关特定环境的元数据。

(如果多个 Debugger 实例正在调试相同的代码,则每个 Debugger 都为给定的环境获得一个单独的 Debugger.Environment 实例。这允许使用每个 Debugger 实例的代码在其自己的 Debugger.Object 实例上放置任何它喜欢的属性,而无需担心干扰其他调试器。)

如果 Debugger.Environment 实例的引用不是调试目标环境,则尝试访问其属性(除了 inspectable)或调用其任何方法都会抛出一个 Error 实例。

Debugger.Environment 实例保护其引用免受垃圾回收器的影响;只要 Debugger.Environment 实例处于活动状态,其引用就会保持活动状态。垃圾回收对 Debugger.Environment 实例没有可见的影响。

Debugger.Environment 原型对象的访问器属性

Debugger.Environment 实例从其原型继承以下访问器属性

inspectable

如果此环境是调试目标环境,并且因此可以进行检查,则为真。否则为假。如果应用于不可检查的环境,则 Debugger.Environment 实例的所有其他属性和方法都会抛出异常。

type

此环境对象的类型,以下值之一

  • “declarative”,表示环境是声明性环境记录。函数调用、对 evallet 块、catch 块等的调用会创建声明性环境记录。

  • “object”,表示环境的绑定是对象的属性。全局对象和 DOM 元素通过对象环境出现在环境链中。(请注意,with 语句有自己的环境类型。)

  • “with”,表示环境是由 with 语句引入的。

scopeKind

如果这是一个声明性环境,则是一个字符串,描述此环境关联的范围类型,或者对于其他类型的环境为 null。可以生成各种可能的范围类型,下面列出了一些可能的值。与类型访问器不同,它执行的分类特定于 SpiderMonkey 的实现,而不是源自 ECMAScript 语言规范中做出的区分。

  • “function”,表示函数的顶级主体范围,用于参数和“var”变量。

  • “function lexical”,表示函数中的顶级词法范围。

parent

封闭此环境的环境(在 ECMAScript 术语中为“外部”环境),或者如果这是最外层环境,则为 null

object

一个 Debugger.Object 实例,引用此环境反映的对象的属性。如果这是一个声明性环境记录,则此访问器会抛出一个 TypeError(因为声明性环境记录没有这样的对象)。"object""with" 环境都有 object 属性,它们提供其属性作为变量绑定所反映的对象。

calleeScript

如果此环境表示对函数 f 的调用的变量环境(函数内的顶级环境,接收 var 定义),则此属性的值是一个 [Debugger.Script][script] 实例,引用 f 的脚本。否则,此属性的值为 null

optimizedOut

如果此环境被优化掉了,则为真。否则为假。例如,其局部变量从未被别名化的函数可能会呈现被优化掉的的环境。当为真时,getVariable 返回一个普通 JavaScript 对象,其 optimizedOut 属性在所有绑定上都为真,而 setVariable 会抛出一个 ReferenceError

Debugger.Environment 原型对象的方法属性

下面描述的方法只能用一个 this 值来调用,该值引用一个 Debugger.Environment 实例;它们不能用作其他类型对象的 方法。

names()

返回一个字符串数组,给出此环境绑定的标识符的名称。结果不包括封闭环境绑定的标识符的名称。

getVariable(name)

返回在此环境中绑定到 name 的变量的值,或者如果此环境未绑定 name,则返回 undefinedName 必须是有效的 ECMAScript 标识符名称的字符串。结果是调试目标值,在大多数情况下。

为了节省空间和减少执行时间,JavaScript 引擎通常会从环境中省略变量。如果给定的变量应该在范围内,但 getVariable 无法生成其值,则返回一个普通 JavaScript 对象(不是 Debugger.Object 实例),其 optimizedOut 属性为 true

除了上述情况外,此方法在另外两种情况下可以返回非调试目标值。如果函数参数缺失,则返回一个普通 JavaScript 对象,其 missingArgument 属性为 true。最后,如果变量名称在环境中绑定但尚未初始化(例如,如果调试目标在初始化表达式中间暂停),则返回一个普通 JavaScript 对象,其 uninitialized 属性为 true

这不是一个 调用函数;如果此调用会导致调试目标代码运行(例如,因为环境是 "with" 环境,并且 name 指的是 with 语句的操作数的访问器属性),则此调用会抛出一个 Debugger.DebuggeeWouldRun 异常。

setVariable(name, value)

value 存储为在此环境中绑定到 name 的变量的值。Name 必须是有效的 ECMAScript 标识符名称的字符串;value 必须是调试目标值。

如果此环境未绑定名为 name 的变量,则抛出一个 ReferenceError

这不是一个调用函数;如果此调用会导致调试目标代码运行,则此调用会抛出一个Debugger.DebuggeeWouldRun异常。

find(name)

返回对最内层环境的引用,从当前环境开始,该环境绑定了name。如果name在此环境的范围内不存在,则返回nullName必须是一个字符串,其值为有效的ECMAScript标识符名称。