繁体   English   中英

用于标记模板文字的TemplateObject数组是否被它们的领域弱引用?

[英]Are TemplateObject arrays for tagged template literals weakly referenced by their realm?

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运行时语义:GetTemplateObject( templateLiteral描述了如何缓存此值:

  1. 领域成为当前的领域记录。
  2. templateRegistry成为领域 。[[TemplateMap]]。

所以它应该是相同的,从使用上面的循环中的tag ,这将是一个很好的属性的密钥。

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

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

会泄漏记忆。

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

我问,因为我已经基于这个假设实现了一些东西 ,但还没弄清楚如何测试它。

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

是的,这正是你要做的事情,这是模板文字的一大特色。

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

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

会泄漏记忆。

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

这是对当前规范的讨论的开放点。 目前的讨论是规范是否应该改为,而不是让[[TemplateMap]]成为全局状态,而是将其改为每个源文本位置。 例如,现在

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

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

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

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

我不知道这里实际做了什么,但是规范确实描述了[[TemplateMap]]从未被清空的领域[[TemplateMap]]。 在循环中评估许多不同的模板标签确实会严重泄漏内存,所以不要这样做

是否可以将该对象用作WeakMap中的键以避免重做工作?

是的,那很好。 如果全局[[TemplateMap]]确实泄漏内存,这将加剧问题,但是当它没有时,那么通过使用映射你不会导致问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM