javascript使用不可变字符串还是可变字符串?我需要一个“字符串生成器”吗?
当前回答
性能提示:
如果必须连接大字符串,请将字符串部分放入数组中,并使用array . join()方法获取整个字符串。这对于连接大量字符串来说可以快很多倍。
JavaScript中没有StringBuilder。
其他回答
它们是不可变的。你不能用像var myString = "abbdef"这样的方法来改变字符串中的字符;myString[2] = 'c'。字符串操作方法,如修剪,切片返回新字符串。
同样地,如果对同一个字符串有两个引用,修改其中一个不会影响另一个
let a = b = "hello";
a = a + " world";
// b is not affected
然而,我总是听到Ash在他的回答中提到的(使用Array。所以我想测试连接字符串的不同方法,并将最快的方法抽象到StringBuilder中。我写了一些测试来验证这是否正确(它不是!)。
我相信这是最快的方法,尽管我一直在想添加一个方法调用可能会使它变慢……
function StringBuilder() {
this._array = [];
this._index = 0;
}
StringBuilder.prototype.append = function (str) {
this._array[this._index] = str;
this._index++;
}
StringBuilder.prototype.toString = function () {
return this._array.join('');
}
这里是性能速度测试。这三个都创造了一个巨大的字符串,由“你好,diggity dog”10万次连接到一个空字符串组成。
我创建了三种类型的测试
使用数组。push和Array.join 使用数组索引来避免数组。push,然后使用Array.join 直串连接
然后我通过将它们抽象为StringBuilderConcat, StringBuilderArrayPush和StringBuilderArrayIndex http://jsperf.com/string-concat-without-sringbuilder/5创建了相同的三个测试,请去那里运行测试,这样我们就可以得到一个很好的示例。请注意,我修复了一个小错误,因此测试数据被擦除,一旦有足够的性能数据,我将更新表。访问http://jsperf.com/string-concat-without-sringbuilder/5查看旧的数据表。
以下是一些数字(Ma5rch 2018最新更新),如果你不想关注链接。每次测试的数值为每秒1000次操作(越高越好)
Browser | Index | Push | Concat | SBIndex | SBPush | SBConcat |
---|---|---|---|---|---|---|
Chrome 71.0.3578 | 988 | 1006 | 2902 | 963 | 1008 | 2902 |
Firefox 65 | 1979 | 1902 | 2197 | 1917 | 1873 | 1953 |
Edge | 593 | 373 | 952 | 361 | 415 | 444 |
Exploder 11 | 655 | 532 | 761 | 537 | 567 | 387 |
Opera 58.0.3135 | 1135 | 1200 | 4357 | 1137 | 1188 | 4294 |
发现
现在,所有的常青树浏览器都能很好地处理字符串连接。数组中。join只支持IE 11 总的来说,Opera是最快的,是Array.join的4倍 其次是Firefox和Array。连接只是稍微慢在FF但相当慢(3倍)在Chrome。 Chrome排名第三,但string concat比Array.join快3倍 创建一个StringBuilder似乎对性能影响不大。
希望其他人会觉得这个有用
不同的测试用例
因为@RoyTinker认为我的测试是有缺陷的,我创建了一个新的情况下,不创建一个大字符串连接相同的字符串,它使用不同的字符为每次迭代。字符串连接似乎还是更快,或者一样快。让我们进行测试
我建议每个人都应该继续考虑其他测试方法,并在下面添加到不同测试用例的新链接。
http://jsperf.com/string-concat-without-sringbuilder/7
JavaScript字符串确实是不可变的。
Javascript中的字符串是不可变的
关于你的问题(在你对Ash的回复的评论中)关于ASP中的StringBuilder。NET Ajax专家们似乎不同意这一点。
Christian Wenz在他的书《编程ASP。NET AJAX (O'Reilly)说,“这种方法对内存没有任何可测量的影响(事实上,实现似乎比标准方法慢一点)。”
另一方面,Gallo等人在他们的书ASP。NET AJAX in Action (Manning),“当要连接的字符串数量较大时,字符串构建器就成为避免巨大性能下降的基本对象。”
我猜您需要自己进行基准测试,不同浏览器的测试结果也可能不同。然而,即使它不能提高性能,对于习惯于用c#或Java等语言编写StringBuilders的程序员来说,它仍然被认为是“有用的”。
string类型的值是不可变的,但是使用string()构造函数创建的string对象是可变的,因为它是一个对象,您可以向它添加新的属性。
> var str = new String("test")
undefined
> str
[String: 'test']
> str.newProp = "some value"
'some value'
> str
{ [String: 'test'] newProp: 'some value' }
同时,虽然您可以添加新的属性,但不能更改已经存在的属性
Chrome控制台测试的截图
总之, 1. 所有字符串类型值(基本类型)都是不可变的。 2. String对象是可变的,但它包含的字符串类型值(基本类型)是不可变的。