根据Is JavaScript a pass-by-reference or pass-by-value language? JavaScript按值传递字符串对象。因此,调用indexOf
方法将触发复制内容。
就我而言,我正在解析一个大字符串来查找数据。我大量使用indexOf
来查找数据。字符串可以大到100-200KB,我可能需要在每次完整扫描时调用indexOf
最多1000次。
我担心这会导致用不必要的复制字符串污染'内存',并可能影响性能。
我的结论是否正确?如果是这样,处理我的任务的正确方法是什么?
潜在地,我可以使用正则表达式,但目前看起来太复杂。
答案 0 :(得分:2)
字符串在Javascript中是一个奇怪的野兽,它们似乎居住在原始类型和对象之间的中间地带。虽然技术上它们被认为是原始的,但在许多情况下,由于它们的不变性,它们可以被视为它们的参考。
鉴于他们是不可变的,如果将字符串的副本传递给任何函数,我将非常非常,因为这将是非常昂贵和完全不必要的。
一个看似简单的方法就是将一个字符串传递给一个函数并更改其中一个字符,以查看它是否在返回时反映在原始字符串中。然而,如上所述,字符串的不变性使得这是不可能的。
可以以间接方式对此进行测试,方法是在数百万次循环中对两个字符串中的一个执行indexOf("a")
。
要搜索的字符串可以是"a"
或"a very long string containing many thousands of characters ..."
。
如果字符串是通过引用传递的,则时间上应该没有明显的差异。传递值应该是可检测的,因为你必须复制数百万次字符串并且短字符串应该比长字符串复制更快。
但是,正如我所说,这可能是不必要的,因为引擎很可能会尽可能优化。
答案 1 :(得分:1)
.indexOf()
仅仅是对字符串的搜索,只是将数字索引返回到字符串中。无需复制,也无需复制。这与Javascript中的值/引用没有任何关系。该操作仅仅是返回索引的搜索。根本不需要复制。
Javascript中的字符串是不可变的。这意味着它们永远不会被更改,并且字符串中的这些索引始终指向字符串中的相同位置。对字符串进行操作以进行更改的任何操作都会返回一个新字符串,而不是旧字符串。
这允许在实现中进行一些有趣的优化。因为字符串是不可变的,所以它可以在引用它的所有代码点之间共享。每当有人调用函数来修改字符串时,它只会返回一个新的字符串对象,该字符串对象是从旧的字符串加上修改后的。
如果您使用.indexOf()
中带有.slice()
之类的索引或类似内容,那么您将把原始字符串的一部分复制到一个新的字符串对象中(可能使用一些额外的内存)。
如果您想自己测试一下,可以随意在大字符串上运行.indexOf()
次操作并观察内存使用情况。