javascript - 标记的模板文字的 TemplateObject 数组是否被其领域弱引用?

标签 javascript ecmascript-6 template-strings weakmap tagged-templates

while (c) {
  tag`str0 ${e} str1`
}

JavaScript 运行时创建一个卡住数组,如 Object.freeze(['str0 ', 'str1']) 但有一个额外的 .raw 属性。

是否可以将该对象用作 WeakMap 中的键以避免每次循环都基于数组重做工作?

const memoTable = new WeakMap
function tag(templateStrings, ...values) {
  let cached = memoTable.get(templateStrings)
  if (!cached) {
    // Compute cached and put it in the table for next time.
  }
  // Do something with cached and values
}

12.2.9.3 Runtime Semantics: GetTemplateObject ( templateLiteral )描述了这个值是如何被缓存的:

  1. Let realm be the current Realm Record.
  2. Let templateRegistry be realm.[[TemplateMap]].

因此在上面的循环中使用 tag 应该是相同的,这对于 key 来说是一个很好的属性。

在我看来,[[TemplateMap]] 必须弱引用模板对象数组,否则

for (let i = 0; i < 1e6; ++i) {
  eval('(() => {})`' + i + '`');
}

会泄漏内存。

我在规范中没有看到任何内容,但对于广泛使用的 JavaScript 引擎来说,是否最终会收集未在可重新输入范围内使用的标记字符串模板的 WeakMap 条目?

我问是因为我已经实现了 something基于这个假设,但还没有想出如何测试它。

最佳答案

Is it okay to use that object as a key in a WeakMap to avoid having to redo work based on the array each time through the loop?

是的,这正是您想要做的,而且它是模板字面量的重要特性之一。

It seems to me that the [[TemplateMap]] would have to weakly reference the template object array because otherwise

for (let i = 0; i < 1e6; ++i) {
  eval('(() => {})`' + i + '`');
}

would leak memory.

它确实泄漏了,因为 [[TemplateMap]] 并不弱。 :(

这是对当前规范的公开讨论点。撰写本文时的讨论是,是否应更改规范以使模板文字成为每个源文本位置,而不是让 [[TemplateMap]] 成为全局状态。例如在撰写本文时:

var id = v => v;
id`tpl` === id`tpl` // true

这有点奇怪。

创建两个单独的模板是否可以接受?如果是这样,那么至少有可能允许您的 eval 示例收集模板。

你可以在这里看到一些讨论,https://github.com/tc39/ecma262/issues/840 ,至少可以暂时解决这个问题。

编辑:

规范确实发生了变化,因此模板现在是按源位置而不是按领域的,因此具有相同内容和不同位置的两个模板将是两个不同的对象。这意味着如果引擎的源文件不再可访问,引擎可能会对模板文字对象进行垃圾回收。

关于javascript - 标记的模板文字的 TemplateObject 数组是否被其领域弱引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48528281/

相关文章:

javascript - Extjs如何解析jsonP响应

ecmascript-6 - es6导入为只读 View 理解

Javascript:如何检查对象数组是否只有一项具有给定值?

javascript - 将字符串转换为模板字符串

javascript - 为什么使用模板字符串时对象解构赋值会抛出错误?

javascript - XSL 解析正在缩短导致 IE 出现问题的脚本标签

javascript - ReactJs中如何传入函数?

javascript - 常规字符串和模板字符串之间的性能差异?

javascript - 当其中一名类(class)成员悬停时突出显示所有类(class)

javascript - react - setState(...): Can only update a mounted or mounting component