Debugger.Object¶
Debugger.Object
实例表示被调试器中的一个对象,提供了面向反射的方法来检查和修改其引用对象。引用对象的属性不会直接显示为 Debugger.Object
实例的属性;调试器只能通过诸如 Debugger.Object.prototype.getOwnPropertyDescriptor
和 Debugger.Object.prototype.defineProperty
之类的方法访问它们,从而确保调试器不会无意中调用引用对象的 getter 和 setter。
SpiderMonkey 为它提供给给定 Debugger
实例的每个被调试器对象精确地创建一个 Debugger.Object
实例:如果调试器通过两种不同的方式遇到同一个对象(例如,对同一个对象调用了两个函数),SpiderMonkey 会每次都向调试器提供相同的 Debugger.Object
实例。这意味着调试器可以使用 ==
运算符来识别两个 Debugger.Object
实例何时引用同一个被调试器对象,并在 Debugger.Object
实例上放置其自身的属性以存储有关特定被调试器对象的元数据。
不同区隔中的 JavaScript 代码可以对同一个对象有不同的视图。例如,在 Firefox 中,特权区隔中的代码会看到内容 DOM 元素对象,而不会看到内容代码对该对象的属性进行的重新定义或扩展。(在 Firefox 术语中,特权代码通过“X 光包装器”看到该元素。)为了确保调试器代码看到的每个对象都与被调试器看到的完全一样,每个 Debugger.Object
实例都将其引用对象呈现为从特定区隔中看到的。此“查看区隔”的选择方式与调试器遇到引用对象的方式相匹配。结果,单个 Debugger
实例实际上可能有多个 Debugger.Object
实例:每个从其查看引用对象的区隔一个。
如果多个 Debugger
实例正在调试相同的代码,则每个 Debugger
都会为给定对象获得一个单独的 Debugger.Object
实例。这允许使用每个 Debugger
实例的代码在其自己的 Debugger.Object
实例上放置任何它喜欢的属性,而无需担心会干扰其他调试器。
虽然大多数 Debugger.Object
实例是由 SpiderMonkey 在将被调试器的行为和状态暴露给调试器的过程中创建的,但调试器可以使用 Debugger.Object.prototype.makeDebuggeeValue
为给定的被调试器对象创建 Debugger.Object
实例,或者使用 Debugger.Object.prototype.copy
和 Debugger.Object.prototype.create
在被调试器区隔中创建新对象,这些对象好像由特定的被调试器全局对象分配一样。
Debugger.Object
实例保护其引用对象免受垃圾回收器的影响;只要 Debugger.Object
实例处于活动状态,引用对象就会保持活动状态。这意味着垃圾回收对 Debugger.Object
实例没有可见的影响。
Debugger.Object 原型的访问器属性¶
Debugger.Object
实例从其原型继承以下访问器属性
proto
¶
引用对象的原型(作为一个新的 Debugger.Object
实例),或者如果它没有原型则为 null
。如果引用对象是脚本代理或其他类型的奇特对象(例如不透明包装器),则此访问器可能会抛出异常。
class
¶
一个字符串,命名引用对象的 ECMAScript [[Class]]
。
callable
¶
如果引用对象是可调用对象(例如函数或函数代理),则为 true
;否则为 false
。
name
¶
引用对象名称,如果它是命名函数。如果引用对象是匿名函数,或者根本不是函数,则为 undefined
。
此访问器返回源代码中 function
关键字之后出现的任何名称,无论该函数是函数声明的结果(将函数绑定到其封闭作用域中的名称)还是函数表达式的结果(将函数绑定到其名称仅在函数体内部)。
displayName
¶
引用对象的显示名称,如果引用对象是具有显示名称的函数。如果引用对象不是函数,或者没有显示名称,则为 undefined
。
如果函数具有给定的名称,则其显示名称与其给定名称相同。在这种情况下,displayName
和 name
属性相等。
如果函数没有名称,SpiderMonkey 会尝试根据其上下文推断一个合适的名称。例如
function f() {} // display name: f (the given name)
var g = function () {}; // display name: g
o.p = function () {}; // display name: o.p
var q = {
r: function () {} // display name: q.r
};
请注意,显示名称可能不是正确的 JavaScript 标识符,甚至不是正确的表达式:即使函数没有立即分配为某个变量或属性的值,我们也会尝试查找有用的名称。因此,我们使用 a/b
来指代在 a 中定义的 b,并使用 a<
来指代出现在分配给 a 的表达式的某个位置的函数。例如
function h() {
var i = function() {}; // display name: h/i
f(function () {}); // display name: h/<
}
var s = f(function () {}); // display name: s<
parameterNames
¶
如果引用对象是调试器函数,则其参数的名称,作为字符串数组。如果引用对象不是调试器函数,或者根本不是函数,则为 undefined
。
如果引用对象是主机函数,并且参数名称不可用,则返回一个数组,其中每个参数一个元素,每个元素都是 undefined
。
如果引用对象是函数代理,则返回一个空数组。
如果函数使用解构参数,则相应的数组元素为 undefined
。例如,如果引用对象以这种方式声明的函数
function f(a, [b, c], {d, e:f}) { ... }
则此 Debugger.Object
实例的 parameterNames
属性将具有以下值
["a", undefined, undefined]
script
¶
如果引用对象是调试器代码的函数,则为该函数的脚本,作为 Debugger.Script
实例。如果引用对象是函数代理或不是调试器代码,则为 undefined
。
environment
¶
如果引用对象是调试器代码的函数,则为一个 Debugger.Environment
实例,表示在创建函数时封闭该函数的词法环境。如果引用对象是函数代理或不是调试器代码,则为 undefined
。
isError
¶
如果引用对象是任何可能包装的 Error,则为 true
;否则为 false
。
errorMessageName
¶
如果引用对象是使用引擎内部消息模板创建的错误,则为一个字符串,表示模板的名称;否则为 undefined
。
errorLineNumber
¶
如果引用对象是 Error 对象,则为创建引用对象的 1 起始行号;否则为 undefined
。
errorColumnNumber
¶
如果引用对象是 Error 对象,则为创建引用对象的 1 起始列号(以 UTF-16 代码单元为单位);否则为 undefined
。
isBoundFunction
¶
如果引用对象是调试器函数,则如果引用对象是绑定函数,则返回 true
;否则返回 false
。如果引用对象不是调试器函数,或者根本不是函数,则返回 undefined
。
isArrowFunction
¶
如果引用对象是一个被调试的函数,则如果该引用对象是一个箭头函数,则返回true
;否则返回false
。如果引用对象不是被调试的函数,或者根本不是函数,则返回undefined
。
isGeneratorFunction
¶
如果引用对象是一个被调试的函数,则如果该引用对象是用function*
表达式或语句创建的,则返回true
,或者如果它是其他类型的函数则返回false
。如果引用对象不是被调试的函数,或者根本不是函数,则为undefined
。(这始终等于obj.script.isGeneratorFunction
,假设obj.script
是Debugger.Script
。)
isAsyncFunction
¶
如果引用对象是一个被调试的函数,则如果该引用对象是一个异步函数,用async function
表达式或语句定义,则返回true
,或者如果它是其他类型的函数则返回false
。如果引用对象不是被调试的函数,或者根本不是函数,则为undefined
。(这始终等于obj.script.isAsyncFunction
,假设obj.script
是Debugger.Script
。)
isClassConstructor
¶
如果引用对象是一个被调试的函数,则如果该引用对象是一个类,则返回true
,或者如果它是其他类型的函数则返回false
。如果引用对象不是被调试的函数,或者根本不是函数,则为undefined
。(这始终等于obj.script.isClassConstructor
,假设obj.script
是Debugger.Script
。)
isPromise
¶
如果引用对象是 Promise,则返回true
;否则返回false
。
boundTargetFunction
¶
如果引用对象是一个绑定的被调试的函数,则这是它的目标函数——绑定到特定this
对象的函数。如果引用对象不是绑定函数,也不是被调试的函数,或者根本不是函数,则为undefined
。
boundThis
¶
如果引用对象是一个绑定的被调试的函数,则这是它绑定的this
值。如果引用对象不是绑定函数,也不是被调试的函数,或者根本不是函数,则为undefined
。
boundArguments
¶
如果引用对象是一个绑定的被调试的函数,则这是一个数组(在调试器对象的隔间中),其中包含它绑定的arguments
对象的被调试的值。如果引用对象不是绑定函数,也不是被调试的函数,或者根本不是函数,则为undefined
。
isProxy
¶
如果引用对象是一个(脚本化的)代理,无论是否被撤销,都返回true
。如果引用对象不是(脚本化的)代理,则返回false
。
proxyTarget
¶
如果引用对象是一个未撤销的(脚本化的)代理,则返回一个Debugger.Object
实例,该实例引用引用对象的 ECMAScript [[ProxyTarget]]
。如果引用对象是一个已撤销的(脚本化的)代理,则返回null
。如果引用对象不是(脚本化的)代理,则返回undefined
。
proxyHandler
¶
如果引用对象是一个未撤销的(脚本化的)代理,则返回一个Debugger.Object
实例,该实例引用引用对象的 ECMAScript [[ProxyHandler]]
。如果引用对象是一个已撤销的(脚本化的)代理,则返回null
。如果引用对象不是(脚本化的)代理,则返回undefined
。
promiseState
¶
如果引用对象是Promise
,则返回一个字符串,指示Promise
是挂起的,还是已完成或已拒绝。此字符串取以下值之一
如果引用对象不是Promise
,则抛出TypeError
。
promiseValue
¶
返回一个被调试的值,表示Promise
已完成的值。
promiseReason
¶
返回一个被调试的值,表示Promise
已被拒绝的值。
promiseAllocationSite
¶
如果引用对象是Promise
,则这是在 promise 分配时捕获的JavaScript 执行堆栈。如果 promise 不是从脚本创建的,则可以返回 null。如果引用对象不是Promise
,则抛出TypeError
异常。
promiseResolutionSite
¶
如果引用对象是Promise
,则这是在 promise 解决时捕获的JavaScript 执行堆栈。如果 promise 不是通过从脚本调用其resolve
或reject
解析函数来解决的,则可以返回 null。如果引用对象不是Promise
,则抛出TypeError
异常。
promiseID
¶
如果引用对象是Promise
,则这是Promise
的进程唯一标识符。使用 e10s,如果这些实例是在不同的进程中创建的,则可以将相同的 ID 潜在分配给多个Promise
实例。如果引用对象不是Promise
,则抛出TypeError
异常。
promiseDependentPromises
¶
如果引用对象是Promise
,则这是一个Array
,其中包含Debugger.Objects
,这些对象引用直接依赖于引用Promise
的 promise。这些是
promise 上
then()
调用的返回值。如果引用
Promise
作为参数之一传递给Promise.all()
,则返回其返回值。如果引用
Promise
作为参数之一传递给Promise.race()
,则返回其返回值。
一旦Promise
稳定下来,它通常会通知其依赖的 promise 并忘记它们,因此这在挂起的 promise 上最有用。
请注意,该Array
仅包含直接依赖于引用Promise
的 promise。它不包含依赖于依赖于引用Promise
的 promise 的 promise。
如果引用对象不是Promise
,则抛出TypeError
异常。
promiseLifetime
¶
如果引用对象是 Promise
,则表示自创建 Promise
以来经过的毫秒数。如果引用对象不是 Promise
,则抛出 TypeError
异常。
promiseTimeToResolution
¶
如果引用对象是 Promise
,则表示从创建 Promise
到其被解析之间经过的毫秒数。如果引用对象尚未被解析或不是 Promise
,则抛出 TypeError
异常。
allocationSite
¶
如果在分配此 Debugger.Object
的引用对象时启用了 对象分配站点跟踪,则返回在分配时捕获的 JavaScript 执行栈。否则,返回 null
。
Debugger.Object 原型的函数属性¶
下面描述的函数只能在 this
值引用 Debugger.Object
实例时调用;它们不能用作其他类型对象的的方法。描述中使用“引用对象”表示“此 Debugger.Object
实例的引用对象”。
除非另有说明,否则这些方法不是 调用函数;如果调用会导致调试目标代码运行(例如,因为它获取或设置了处理程序为调试目标代码的访问器属性,或者因为引用对象是代理且其陷阱是调试目标代码),则调用会抛出 Debugger.DebuggeeWouldRun
异常。
如果引用对象不是原生对象,则这些方法可能会抛出异常。即使是简单的访问器,例如 isExtensible
,如果引用对象是代理或某种奇特的对象(如不透明包装器),也可能会抛出异常。
getProperty(key, [receiver])
¶
返回一个 完成值,其中“return”为引用对象的名称为 key 的属性的值,如果它没有这样的属性,则为 undefined
。key 必须是字符串或符号;receiver 必须是调试目标值。如果属性是 getter,它将使用 receiver 作为接收者进行评估,如果省略则默认为 Debugger.Object
。在调用期间,所有现有的处理程序方法、断点等都保持活动状态。
setProperty(key, value<, [receiver])
¶
将 value 存储为引用对象的名称为 key 的属性的值,如果该属性不存在则创建它。key 必须是字符串或符号;value 和 receiver 必须是调试目标值。如果属性是 setter,它将使用 receiver 作为接收者进行评估,如果省略则默认为 Debugger.Object
。返回一个 完成值,其中“return”为成功/失败布尔值,或者“throw”为属性赋值期间抛出的异常。在调用期间,所有现有的处理程序方法、断点等都保持活动状态。
getOwnPropertyDescriptor(key)
¶
返回引用对象的名称为 key 的属性的属性描述符。如果引用对象没有这样的属性,则返回 undefined
。(此函数的行为类似于标准的 Object.getOwnPropertyDescriptor
函数,除了被检查的对象是隐式的;返回的属性描述符就像调试器的全局对象范围内的代码一样分配(因此在调试器的隔间中);并且它的 value
、get
和 set
属性(如果存在)是调试目标值。)
getOwnPropertyNames()
¶
返回一个字符串数组,这些字符串命名了引用对象的所有自身属性,就像在调试目标中调用了 Object.getOwnPropertyNames(referent)
,并将结果复制到调试器的全局对象的作用域中。
getOwnPropertyNamesLength()
¶
返回引用对象自身属性的数量。
getOwnPropertySymbols()
¶
返回一个字符串数组,这些字符串命名了引用对象的所有自身符号,就像在调试目标中调用了 Object.getOwnPropertySymbols(referent)
,并将结果复制到调试器的全局对象的作用域中。
defineProperty(key, attributes)
¶
根据属性描述符 descriptor 定义引用对象上名为 key 的属性。attributes 的任何 value
、get
和 set
属性必须是调试目标值。(此函数的行为类似于 Object.defineProperty
,除了目标对象是隐式的,并且与函数和描述符位于不同的隔间中。)
defineProperties(properties)
¶
将 properties 给出的属性添加到引用对象。(此函数的行为类似于 Object.defineProperties
,除了目标对象是隐式的,并且与 properties 参数位于不同的隔间中。)
deleteProperty(key)
¶
删除引用对象的名称为 key 的属性。如果属性成功删除或引用对象没有这样的属性,则返回 true。如果属性不可配置,则返回 false。
seal()
¶
防止向引用对象添加或从中删除属性。返回此 Debugger.Object
实例。(此函数的行为类似于标准的 Object.seal
函数,除了要密封的对象是隐式的,并且与调用者位于不同的隔间中。)
freeze()
¶
防止向引用对象添加或从中删除属性,并将每个属性标记为不可写。返回此 Debugger.Object
实例。(此函数的行为类似于标准的 Object.freeze
函数,除了要密封的对象是隐式的,并且与调用者位于不同的隔间中。)
preventExtensions()
¶
防止向引用对象添加属性。(此函数的行为类似于标准的 Object.preventExtensions
函数,除了要操作的对象是隐式的,并且与调用者位于不同的隔间中。)
isSealed()
¶
如果引用对象已密封,则返回 true,即如果它不可扩展,并且其所有属性都已标记为不可配置。(此函数的行为类似于标准的 Object.isSealed
函数,除了被检查的对象是隐式的,并且与调用者位于不同的隔间中。)
isFrozen()
¶
如果引用对象已冻结,则返回 true,即如果它不可扩展,并且其所有属性都已标记为不可配置和只读。(此函数的行为类似于标准的 Object.isFrozen
函数,除了被检查的对象是隐式的,并且与调用者位于不同的隔间中。)
isExtensible()
¶
如果引用对象可扩展,则返回 true,即如果可以在其上定义新的属性。(此函数的行为类似于标准的 Object.isExtensible
函数,除了被检查的对象是隐式的,并且与调用者位于不同的隔间中。)
makeDebuggeeValue(value)
¶
返回表示调试目标中 value 的调试目标值。如果 value 是一个原始值,我们将其原样返回;如果 value 是一个对象,我们返回表示该对象的 Debugger.Object
实例,并将其适当地包装以供在此 Debugger.Object
的引用对象所在的隔间中使用。
请注意,如果 value 是一个对象,它不必是在调试目标全局中分配的对象,甚至不必是调试目标隔间中的对象;它可以是调试器希望用作调试目标值的任何对象。
如上所述,每个 Debugger.Object
实例都以从特定隔间看到的视角呈现其引用对象。给定一个 Debugger.Object
实例 d 和一个对象 o,调用 d.makeDebuggeeValue(o)
将返回一个 Debugger.Object
实例,该实例以 d 的隔间中的代码将看到的方式呈现 o。
isSameNative(value)
¶
如果 value 是调试器隔间中的原生函数,则返回引用对象是否为同一 C++ 原生的原生函数。
isSameNativeWithJitInfo(value)
¶
如果 value 是调试器隔间中的原生函数,则返回引用对象是否为具有相同 JSJitInfo 指针值的同一 C++ 原生的原生函数。
这可用于区分具有共享原生函数实现但 JSJitInfo 指针不同的函数,以定义底层功能。
isNativeGetterWithJitInfo()
¶
返回引用对象是否为具有 JSJitInfo 的原生 getter 函数。
decompile([pretty])
¶
如果引用对象是调试目标代码的函数,则返回一个 JavaScript 源代码字符串,该字符串等效于引用函数的效果和结果。如果 pretty 存在且为 true
,则生成带缩进和换行的代码。如果引用对象不是调试目标代码的函数,则返回 undefined
。
call(this, argument, ...)
¶
如果引用对象是可调用的,则使用给定的this值和argument值调用它,并返回一个完成值,描述调用如何完成。This应该是一个调试目标值,或者{ asConstructor: true }
以将引用对象作为构造函数调用,在这种情况下,SpiderMonkey 会自行提供一个合适的this
值。每个argument都必须是一个调试目标值。在调用期间,所有现有的处理程序方法、断点等都保持活动状态。如果引用对象不可调用,则抛出TypeError
。此函数遵循调用函数约定。
注意:如果此方法在拥有Debugger 对象且该对象具有onNativeCall处理程序的对象上调用,则在评估期间,只有与该调试器关联的对象上的钩子才会被调用。
apply(this, arguments)
¶
如果引用对象是可调用的,则使用给定的this值和arguments中的参数值调用它,并返回一个完成值,描述调用如何完成。This应该是一个调试目标值,或者{ asConstructor: true }
以将function作为构造函数调用,在这种情况下,SpiderMonkey 会自行提供一个合适的this
值。Arguments必须是调试目标值的数组(在调试器中),或者null
或undefined
,它们被视为空数组。在调用期间,所有现有的处理程序方法、断点等都保持活动状态。如果引用对象不可调用,则抛出TypeError
。此函数遵循调用函数约定。
注意:如果此方法在拥有Debugger 对象且该对象具有onNativeCall处理程序的对象上调用,则在评估期间,只有与该调试器关联的对象上的钩子才会被调用。
executeInGlobal(code, [options])
¶
如果引用对象是全局对象,则在该全局环境中评估code,并返回一个完成值,描述它如何完成。Code是一个字符串。在调用期间,所有现有的处理程序方法、断点等都保持活动状态(下面有待补充说明)。此函数遵循调用函数约定。如果引用对象不是全局对象,则抛出TypeError
异常。
当Code包含Use Strict Directive时,它会被解释为严格模式代码。
此评估在语义上等同于在全局级别执行语句,而不是间接eval。无论code是否为严格模式代码,code中的变量声明都会影响引用全局对象。
Options参数与Debugger.Frame.prototype.eval
相同。
注意:如果此方法在拥有Debugger 对象且该对象具有onNativeCall处理程序的对象上调用,则在评估期间,只有与该调试器关联的对象上的钩子才会被调用。
executeInGlobalWithBindings(code, bindings, [options])
¶
类似于executeInGlobal
,但使用引用对象作为变量对象来评估code,但使用扩展了对象bindings中绑定的词法环境。
使用bindings指定的绑定创建一个额外的环境。该环境包含与bindings的每个自身可枚举属性相对应的绑定,其中属性名称name作为绑定名称,属性值value作为绑定的初始值。
如果未指定options.useInnerBindings
或将其指定为false
,则它会模拟将绑定环境放置在全局外部的位置,这意味着,如果绑定与code中声明的任何全局变量或任何现有的全局变量冲突,则该绑定将被忽略。
如果将options.useInnerBindings
指定为true
,则它会直接执行将绑定环境放置在全局内部的操作,并且提供的绑定会隐藏全局变量。
每个value都必须是一个调试目标值。
这不像with
语句:code可以访问、分配和删除引入的绑定,而不会对传递的bindings对象产生任何影响,因为属性在每次调用时都会复制到一个新对象中。
此方法允许调试器代码引入对给定调试目标代码可见的临时绑定,并且这些绑定引用调试器持有的调试目标值,并且这样做不会修改任何现有的调试目标环境。
请注意,与executeInGlobal
一样,它包含的任何声明都会影响引用全局对象,即使code是在根据bindings扩展的环境中进行评估的。(在ECMAScript规范中使用的术语中,code的执行上下文的VariableEnvironment
是引用对象,而bindings出现在一个新的声明环境中,该环境是eval代码的LexicalEnvironment
。)
Options参数与Debugger.Frame.prototype.eval
相同。
注意:如果此方法在拥有Debugger 对象且该对象具有onNativeCall处理程序的对象上调用,则在评估期间,只有与该调试器关联的对象上的钩子才会被调用。
createSource(options)
¶
如果引用对象是全局对象,则在全局对象的领域中返回一个新的JavaScript源,其属性根据options
对象填充。如果引用对象不是全局对象,则抛出TypeError
异常。options
对象可以具有以下属性
text
:源中JavaScript的字符串内容。url
:结果源应关联的URL。startLine
:源的起始行。startColumn
:源的起始列。sourceMapURL
:可选URL,指定源的源映射URL。如果未指定,则如果源文本指定,则可以填写源映射URL。isScriptElement
:可选布尔值,如果指定,则会将源的introductionType
设置为"inlineScript"
。否则,源的introductionType
将为undefined
。
asEnvironment()
¶
如果引用对象是全局对象,则返回表示引用对象全局词法作用域的Debugger.Environment
实例。全局词法作用域的封闭作用域是全局对象。如果引用对象不是全局对象,则抛出TypeError
。
unwrap()
¶
如果引用对象是此Debugger.Object
的区室允许解包的包装器,则返回一个Debugger.Object
实例,该实例引用包装的对象。如果我们不允许解包引用对象,则返回null
。如果引用对象不是包装器,则返回此Debugger.Object
实例不变。
unsafeDereference()
¶
返回此Debugger.Object
实例的引用对象。
如果引用对象是内部对象(例如,HTML5 Window
对象),则返回相应的外部对象(例如,HTML5 WindowProxy
对象)。这使得unsafeDereference
在生成适合调试目标代码直接使用的值方面更有用,而无需使用调用函数。
此方法穿透旨在保护调试器代码免受调试目标代码影响的Debugger.Object
实例的膜,并允许调试器代码通过标准的跨区室包装器访问调试目标对象,而不是通过Debugger.Object
的面向反射的接口。此方法使大型代码库更容易逐渐适应此Debugger API:代码的已适应部分可以使用Debugger.Object
实例,但使用此方法将直接对象引用传递给尚未更新的代码。
forceLexicalInitializationByName(binding)
¶
如果binding处于未初始化状态,则将其初始化为undefined并返回true,否则不执行任何操作并返回false。
getPromiseReactions
¶
如果引用对象是Promise
或其跨区室包装器,则它会返回一个对象数组,这些对象描述添加到promise的反应记录。有几种不同类型的反应记录
使用
then
或catch
添加的反应记录的数组条目具有{ resolve: F, reject: F, result: P }
的形式,其中每个F
都是一个Debugger.Object
,引用一个函数对象,而P
是将使用调用它们的结果解析的promise。在某些情况下,
resolve
和reject
属性可能不存在。对then
的调用可以省略拒绝处理程序,而对catch
的调用会省略解析处理程序。此外,各种promise工具会将类似的记录创建为内部实现细节,创建不可表示为JavaScript函数的处理程序。当一个promise
P1
被解析为另一个promiseP2
(以至于解析P2
以相同的方式解析P1
)时,这会向P2
添加一个反应记录。该反应记录的数组条目只是表示P1
的Debugger.Object
。请注意,如果
P1
和P2
位于不同的区室中,则将P1
解析为P2
会创建与对then
或catch
的调用相同的反应记录,其中P1
仅存储在resolve
和reject
函数的私有槽中,而不是直接从反应记录中获取。一个
await
表达式在其操作数上调用PromiseResolve
以获取一个promiseP
,然后向P
添加一个反应记录,以适当地恢复挂起的调用。该反应记录的数组条目是表示挂起调用的Debugger.Frame
。如果
await
的操作数A
是具有标准构造函数的原生promise,则PromiseResolve
只会返回不变的A
,并且用于恢复挂起调用的反应记录将添加到A
的列表中。但是,如果A
是某种其他类型的“thenable”,则PromiseResolve
会创建一个新的promise并排队一个作业来调用A
的then
方法;这可能会从awaitees到awaiters产生更多间接链。JS::AddPromiseReactions
和JS::AddPromiseReactionsIgnoringUnhandledRejection
创建一个反应记录,其promise字段为null
。