You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

V8/Node.js中数组存字符串、对象属性赋值时是否复制字符串?

在V8/Node.js中原始类型推入数组或赋值给对象属性的内存机制

核心结论

在V8/Node.js环境中,字符串、数字、布尔这类原始类型(注:V8中字符串是不可变对象,但表现出原始类型特性),当推入数组或赋值给对象属性时,不会复制字符串/原始值的内容,而是复用指向内存中同一实例的引用。

逐一解释你的示例场景

1. 重新赋值变量不影响数组内容的原因

let array = []
let x = 'foo'
array.push(x)
x = 'bar'
console.log(array) //=> ['foo']

这里的“值传递”是指将x持有的引用(指向'foo'字符串实例)复制给数组元素。当你把x重新赋值为'bar'时,只是改变了x变量自身的引用指向,数组元素仍保留着指向原'foo'实例的引用,因此数组内容不受影响。这并不代表数组存储了'foo'的内容副本。

2. 多次推入同一字符串不会重复占用内存

let array = []
let x = 'foo'
array.push(x)
array.push(x)
array.push(x)

V8内置**字符串驻留(String Interning)**优化:相同的字符串字面量会被存储在内存中的同一个实例里。无论你将x推入数组多少次,数组的每个元素都是指向同一个'foo'实例的引用,内存中只会保留一份'foo'的内容,不会因多次推入增加字符串本身的内存开销。

3. 同一字符串赋值给多个对象属性同理

let object = {}
let x = 'foo'
object.a = x
object.b = x
object.c = x

和数组场景完全一致:object.a、object.b、object.c均指向同一个'foo'字符串实例,内存中仅存在一份'foo'的内容,不会因多属性赋值复制字符串内容。

对你的内存计算需求的建议

如果你用Buffer.byteLength(text, 'utf8')计算字典树的大致内存占用,只需统计每个唯一字符串的长度即可。重复的引用不会带来额外的字符串内容内存开销,无需累加每个引用对应的字符串长度。

纠正错误说法

所谓“内置原始类型推入数组时是复制”的表述不准确——这里的“复制”仅指复制引用,而非复制字符串的实际内容。V8的字符串驻留机制确保了相同字符串的内存复用,不会产生内容副本。

内容的提问来源于stack exchange,提问作者Lance Pollard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:51:11