我一直对JavaScript函数的“参数按值传递”的特征有些顾虑。尤其在参数为字符串,且字符串“很长”时,“按值传递参数”会不会导致性能问题呢?请大佬们帮助答疑解惑,谢谢!
例如,下面的函数会不会有性能问题?
let str = '一个很长的字符串'; //1. 内存中拥有了第一份str字符串
function checkString(str) {
for(const ch of str) { //5. 此时的str是内存中的第三份str字符串
...
}
return str.length < 10000 ? '' : str;
}
function transString(str) { //3. 此str是内存中的第二份str字符串
if(checkString(str)) { //4. 再次【复制】str字符串,并传入checkString函数中
....
}
}
transString(str); //2. 【复制】第1行的str字符串,并传入transString函数内部
我的分析是:执行transString函数需要复制两次str字符串,且复制后,在checkString函数执行时,内存中总共出现了三份str字符串。并且,由于str字符串是一个很大的字符串,所以每次复制都需要消耗很长的运行时间,并需要要多占据一份很大的内存。由此推断transString函数的性能很是低下。
这个分析纯属我瞎猜,不知道对不对。请大佬们帮助解惑,谢谢了!
javascript里面的字符串的确是按值传递的可是别忘了他是immutable的啊,可以很轻松的基于这个特性做出很多的优化,比如string数据结构就可用用这样的数据结构描述
这样的话字符串的赋值产生的性能问题就变得不值一提,不过多长字符串的复制都是O(1)的时间复杂度,这样设计的好处还有就是想substring,substr,slice这种mutate字符串的操作都能在O(1)的时间复杂度内完成,因为只用改下首尾偏移量然后在返回就行,相比之下在c++中如果不注意的话反而会因为字符串的mutable特性,再加上可选择引用传递或者值传递,产生更多逻辑或者性能的问题,像javascript这种高抽象的语言一般都会选择缺失一些灵活性,但是减少很多心智负担,更不容易写出有内存泄漏或者性能问题的代码
顺便附上算法4对java中字符串的描述

