首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何强制JavaScript对字符串进行深度复制?

如何强制JavaScript对字符串进行深度复制?
EN

Stack Overflow用户
提问于 2015-07-30 07:25:16
回答 8查看 113K关注 0票数 79

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

代码语言:javascript
复制
var myClass = {
  ids: {}
  myFunc: function(huge_string) {
     var id = huge_string.substr(0,2);
     ids[id] = true;
  }
}

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

如何复制字符串id,以便不维护对huge_string的引用,并且可以对huge_string进行垃圾回收?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2015-07-31 04:41:07

ECMAScript的JavaScript实现可以因浏览器而异,但是对于Chrome,有许多字符串操作(substr、slice、regex等)。只需保留对原始字符串的引用,而不是复制字符串。这是Chrome (Bug #2869)中的一个已知问题。要强制复制字符串,请使用以下代码:

代码语言:javascript
复制
var string_copy = (' ' + original_string).slice(1);

此代码的工作方式是在字符串的前面附加一个空格。在Chrome的实现中,这种连接会产生一个字符串副本。则可以引用空格之后的子串。

解决方案的这个问题已在此处重新创建:http://jsfiddle.net/ouvv4kbs/1/

警告:加载需要很长时间,请打开Chrome调试控制台查看进度打印输出。

代码语言:javascript
复制
// We would expect this program to use ~1 MB of memory, however taking
// a Heap Snapshot will show that this program uses ~100 MB of memory.
// If the processed data size is increased to ~1 GB, the Chrome tab
// will crash due to running out of memory.

function randomString(length) {
  var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  var result = '';
  for (var i = 0; i < length; i++) {
    result +=
        alphabet[Math.round(Math.random() * (alphabet.length - 1))];
  }
  return result;
};

var substrings = [];
var extractSubstring = function(huge_string) {
  var substring = huge_string.substr(0, 100 * 1000 /* 100 KB */);
  // Uncommenting this line will force a copy of the string and allow
  // the unused memory to be garbage collected
  // substring = (' ' + substring).slice(1);
  substrings.push(substring);
};

// Process 100 MB of data, but only keep 1 MB.
for (var i =  0; i < 10; i++) {
  console.log(10 * (i + 1) + 'MB processed');
  var huge_string = randomString(10 * 1000 * 1000 /* 10 MB */);
  extractSubstring(huge_string);
}

// Do something which will keep a reference to substrings around and
// prevent it from being garbage collected.
setInterval(function() {
  var i = Math.round(Math.random() * (substrings.length - 1));
  document.body.innerHTML = substrings[i].substr(0, 10);
}, 2000);

票数 79
EN

Stack Overflow用户

发布于 2019-12-12 03:46:48

不确定如何测试,但使用字符串插值来创建新的字符串变量是否有效?

代码语言:javascript
复制
newString = `${oldString}`
票数 26
EN

Stack Overflow用户

发布于 2018-05-29 13:37:27

我对字符串、对象、数组等使用Object.assign()方法:

代码语言:javascript
复制
const newStr = Object.assign("", myStr);
const newObj = Object.assign({}, myObj);
const newArr = Object.assign([], myArr);

请注意,Object.assign仅复制对象内的键及其属性值(仅一级)。有关深度克隆嵌套对象的信息,请参考以下示例:

代码语言:javascript
复制
let obj100 = { a:0, b:{ c:0 } };
let obj200 = JSON.parse(JSON.stringify(obj100));
obj100.a = 99; obj100.b.c = 99; // No effect on obj200
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31712808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档