JavaScript 字符串是不可变的吗?我需要JavaScript中的“字符串生成器”吗?
javascript使用不可变或可变字符串吗?我需要“字符串生成器”吗?
javascript使用不可变或可变字符串吗?我需要“字符串生成器”吗?
它们是不可变的。不能使用类似 的内容更改字符串中的字符。字符串操作方法(如 trim
、slice)
将返回新字符串。var myString = "abbdef"; myString[2] = 'c'
同样,如果您有两个对同一字符串的引用,则修改其中一个不会影响另一个
let a = b = "hello";
a = a + " world";
// b is not affected
但是,我总是听到Ash在他的答案中提到的(使用Array.join进行串联更快),所以我想测试连接字符串和以最快的方式抽象到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('');
}
以下是性能速度测试。他们三个人都创造了一个巨大的字符串,由将十万次连接成一个空字符串组成。"Hello diggity dog"
我创建了三种类型的测试
Array.push
Array.join
Array.push
Array.join
然后,我通过将它们抽象为 创建了相同的三个测试,并 http://jsperf.com/string-concat-without-sringbuilder/5 请去那里运行测试,以便我们可以得到一个很好的样本。请注意,我修复了一个小错误,因此测试的数据被擦除了,一旦有足够的性能数据,我将更新表。转到旧数据表的 http://jsperf.com/string-concat-without-sringbuilder/5。StringBuilderConcat
StringBuilderArrayPush
StringBuilderArrayIndex
以下是一些数字(Ma5rch 2018中的最新更新),如果您不想点击该链接。每个测试的数字以 1000 次操作/秒为单位(越高越好)
浏览器 | 指数 | 推 | 康卡特 | SBIndex | SBPush | SBConcat |
---|---|---|---|---|---|---|
铬 71.0.3578 | 988 | 1006 | 2902 | 963 | 1008 | 2902 |
火狐 65 | 1979 | 1902 | 2197 | 1917 | 1873 | 1953 |
边缘 | 593 | 373 | 952 | 361 | 415 | 444 |
爆炸物 11 | 655 | 532 | 761 | 537 | 567 | 387 |
歌剧 58.0.3135 | 1135 | 1200 | 4357 | 1137 | 1188 | 4294 |
发现
如今,所有常青浏览器都能很好地处理字符串连接。 只帮助IE 11Array.join
总体而言,Opera速度最快,是Array.join的4倍。
Firefox排在第二位,在FF中仅略慢,但在Chrome中则相当慢(3倍)。Array.join
Chrome 排名第三,但 string concat 比 Array.join 快 3 倍
创建一个 StringBuilder 似乎不会对性能产生太大影响。
希望其他人发现这很有用
不同的测试用例
由于@RoyTinker认为我的测试有缺陷,因此我创建了一个新案例,该案例不会通过连接同一字符串来创建大字符串,而是在每次迭代中使用不同的字符。字符串串联似乎仍然更快或一样快。让我们运行这些测试。
我建议每个人都应该继续考虑其他方法来测试这一点,并随时在下面的不同测试用例中添加新链接。
来自犀牛书:
在JavaScript中,字符串是不可变的对象,这意味着其中的字符可能不会被更改,并且对字符串的任何操作实际上都会创建新字符串。字符串是按引用分配的,而不是按值分配的。通常,当按引用分配对象时,通过一个引用对对象所做的更改将通过对该对象的所有其他引用可见。但是,由于字符串无法更改,因此您可以对字符串对象进行多个引用,而不必担心字符串值会在您不知情的情况下更改