如何强制JavaScript深度复制一个字符串?

94

我有一些JavaScript代码,看起来像这样:

var myClass = {
  ids: {}
  myFunc: function(huge_string) {
     var id = huge_string.substr(0,2);
     ids[id] = true;
  }
}

之后该函数被调用时使用了一些大字符串(100 MB+)。我只想保存在每个字符串中找到的一个短id。然而,Google Chrome的substring函数(实际上是我的代码中的正则表达式)仅返回一个“切片字符串”对象,它引用原始字符串。因此,在对myFunc进行一系列调用后,我的Chrome选项卡会耗尽内存,因为临时的huge_string对象不能被垃圾收集。

我应该如何复制字符串id,以便不维护对huge_string 的引用,并且可以回收huge_string?

enter image description here


3
“substring函数(实际上是我的代码中的正则表达式)只返回一个“切片字符串”对象,该对象引用原始字符串。” - 什么? .substr().substring().slice()和相关的正则表达式函数都会返回一个新的字符串。调用myClass.myFunc()的其他代码是否保留了对您巨大字符串的引用?如果您的真实代码更复杂,是否意外地在闭包中保留了这些巨大的字符串? - nnnnnn
3
@nnnnnn 无法确定JavaScript中的“新”字符串data; 实现可以共享底层数据而不违反ECMAScript的任何部分。 Firefox有半打不同的字符串实现(特别是请参见JSDependentString),如果Chrome具有类似的优化,则我不会感到惊讶(这可能在某些边缘情况下表现不佳)。 话虽如此..如果这是一个误导,我也不会感到非常惊讶。 - user2864740
2
读者参考: https://dev59.com/MWIj5IYBdhLWcg3wMiYu - user2864740
4
这个漏洞报告 #2869中包含了一个解决方法:(' ' + src).slice(1)。目前还没有官方的解决方案。 - user2864740
1
在将脚本转换为"use strict;"时,我遇到了这个问题,我们正在写入一个现在只读的字符串文字,并且得到了一个"Cannot assign to read only property '0' of string"的错误。 - Alex Dixon
显示剩余5条评论
11个回答

-1

我遇到了这个问题,这是我应对它的方式:

let copy_string = [];
copy_string.splice(0, 0, str);

我相信这会深度复制字符串到copy_string。


虽然从技术上讲,str 变量将被推入 copy_string 中,但 copy_string 是一个数组,因此您必须像这样完成它:const copiedVariable = copy_string.join(''),以将数组重新组合成字符串。 - Marcus Parsons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接