gpt4 book ai didi

javascript - 函数属性保存对文档片段的引用 : when to use cloneNode?

转载 作者:行者123 更新时间:2023-11-28 03:10:26 25 4
gpt4 key购买 nike

我无法理解何时对对象的数据分配是引用以及何时创建该对象的副本。我以为我明白了,但下面的例子不符合我对它的简单理解。

事件处理程序开始执行以下一系列步骤。
Promise.allSettled( [ gather_write, get_build ] ).then( test );

promise gather_writeget_build执行不相关的功能。第一个从 DOM 收集一些数据并将其写入数据库。第二个从数据库检索数据并构建文档片段。如果两者都满足,则 DOM 中的节点将被片段替换。

这里显示的代码太多,但是 get_build成功从数据库获取数据后,调用一个单独的函数来构建文档片段,并将其结果作为解析对象的属性返回。效果很好;然后我想尝试在 gather_write 的情况下向用户提供选项被拒绝并 get_build已完成,需要临时存储文档片段。因此,不要返回它并将其传递回 Promise.allSettled ,它存储在构建它的函数的属性中。

在同步函数build代码设置为:

function build()
{
let f;
try
{
f = document.createFragment();
// ...build the fragment...
build.html = f;
}
catch(e)
{ }
finally
{ f = null; }
} // close build

函数build必须在 promise 之前完成get_build可以解决,之后Promise.allSettled可以评估;并且,如果两个 promise 都满足,则用存储在 build.html 中的新建片段替换 DOM 节点的函数可以被调用。我以为build.html将是对节点对象 f 的引用而且,自从 ffinally 中设置为 null block ,这将在上述所有操作完成之前发生,并且当代码使用 build.html 时发生最终运行时它将指向空值而不是片段。所以,赋值语句应该是 build.html = f.cloneNode(true)

但是,无论是否使用f.cloneNode,该过程都可以正常工作。 。您能解释一下原因吗?如果没有必要,我不希望浏览器采取克隆片段的步骤,但在不理解为什么它无需克隆的情况下也能工作的情况下,犹豫是否将其排除。

谢谢。

最佳答案

您可以将每个变量名称视为指向内存位置的指针。将变量名称设置为 null 不会改变该变量所包含的内容;它所做的只是将变量名称指向的内容从先前的引用(此处为文档片段)更改为新的引用(空)。所以,当你这样做时

f = document.createFragment();
build.html = f;

然后,无论 f 变量名称将来是否/如何重新分配,build.html 都不会改变,因为它继续指向文档分段。更改 build.html 的唯一方法是片段发生变异(例如在重新分配之前分配给 f 的属性) ,或调用片段的方法之一)。

这是此行为的另一个最小示例:

function foo() {
let f = { prop: 'val' };
foo.f = f;
f = null;
}

foo();

console.log(foo.f);

这里,虽然 f 被设置为 null,但对象 { prop: 'val' } 保持完整且未发生变化,因此foo.f 获取对该对象的引用,并且即使在重新分配 f 后仍继续保留该引用。

使用您的代码,由于内存中的片段仍保留在内存中,并且即使在重新分配 f 之后,build.html 仍保留对该片段的引用,克隆该片段只是不必要的开销;请随意忽略它。

另一种可视化方式是您的代码:

function build() {
let f;
try {
f = document.createFragment();
// ...build the fragment...
build.html = f;
} catch (e) {} finally {
f = null;
}
}

相当于

function build() {
let f;
try {
// Create the object in memory:
<MemRef#513513> = document.createFragment();
// Point the variable `f` to that created object:
f = <MemRef#513513>;
// ...build the fragment...
build.html = <MemRef#513513>;
} catch (e) {} finally {
f = <MemRef#Null>;
}
}

关于javascript - 函数属性保存对文档片段的引用 : when to use cloneNode?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60178684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com