提问者:小点点

v8引擎中DOM包装器的混乱解释


我试图学习为什么V8 API是这样结构的设计,并找到了一个有用的文档,关于各种事物之间的关系,如隔离,上下文等:链接到V8绑定

在那里,我被某一段话弄糊涂了:

出于兼容性的原因,我们需要确保只要底层C++DOM对象是活的,就会将相同的DOM包装器返回到JavaScript。 我们不应该为同一个C++DOM对象返回不同的DOM包装。

下面是一个例子:

var div = document.createElement("div");
div.foo = 1234;  // expando
var p = document.createElement("p");
p.appendChild(div);
div = null;
gc();
console.log(p.firstChild.foo);  // This should be 1234, not undefined

为了实现这样的语义,即只要底层C++DOM对象是活动的,相同的DOM包装器就会返回到JavaScript,我们需要一个从C++DOM对象到DOM包装器的映射。 此外,我们需要在每个世界中沙箱DOM包装器。 为了满足需求,我们使每个世界都拥有一个DOM包装器存储,该存储存储从C++DOM对象到该世界中的DOM包装器的映射。

因此,我们在一个隔离体中有多个DOM包装器存储。 主世界的映射是用ScriptWrappable编写的。 如果ScriptWrappable::Main_World_Wrapper_具有非空值,则它是主世界的C++DOM对象的DOM包装器。 其他世界的映射写在DOMDATASTORE中。

我仍在努力理解整段内容,但具体的代码示例和直接的解释对我来说没有意义。 我从来没有想到代码片段会打印undefined,即使它是纯JavaScript API。

我觉得这个例子是不正确的,但如果没有一个恰当的例子,我很难理解这个概念。


共1个答案

匿名用户

属性foo是在JS对象包装器上添加的,而不是在内部C++DOM对象上添加的。

因此,当调用GC()(garbagecollection)时,最初声明为div的JS对象及其foo属性将消失(在GC之前,该变量被设置为null)。

如果JS对象DOM包装器并不总是同一个对象,那么通过p.firstchild检索C++DOM对象将返回另一个新的JS对象DOM包装器,它没有foo属性。

但是由于它们确保包装总是相同的,无论调用它的上下文是什么,属性仍然可用。