还真有可能是返回的字符串在底层对原字符串进行了引用导致未被 GC。参见这篇文章 奇技淫巧学 V8 之六,字符串在 V8 内的表达,文中提到,对原 string 进行 substring/slice 底层依然会保留完整的原字符串在堆上的。
就这个问题有一个办法可以规避,用 String.fromCharCode(str.charCodeAt(i))
转成每个字符的 unicode 再转回去。
就这个问题有一个办法可以规避,可以获取每个字符然后重新造字符串来消除底层 SliceString 的结构。
function getOthersHref(htm) {
const index = htm.indexOf('name="description"'),
lastIndex = htm.indexOf('<', index),
match = (htm.substring(index, lastIndex + 1) || '').match(/>(.+?)</) || [];
return cloneStr((match[1] || '').trim());
}
//function cloneStr(str) {
// let copied = '';
// for(let i=0; i<str.length; i++) {
// copied += String.fromCharCode(str.charCodeAt(i));
// }
// return copied;
//}
const cloneStr = str => [...str].join('');
还好你的 href 也不会很长,这样并不会影响性能。
做一个实验,证明 slice substring match trim 后最终返回的字符串仍然在底层引用了原字符串。
clone 后貌似还有俩内部的 regexp_last_match_info 在引用者。
随便运行一个正则,没了,貌似是系统内部保存了最后一次正则相关的内容?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…