JS编程建议——34:字符串是非值操作

  1. 云栖社区>
  2. 博客>
  3. 正文

JS编程建议——34:字符串是非值操作

zhanginzaghi 2017-12-14 08:55:28 浏览773
展开阅读全文

建议34:字符串是非值操作
在字符串的复制和传递过程中,JavaScript解释器以引用方式来实现对字符串的操作。将字符串数据存储到堆区,然后把字符串的引用地址存储在字符串变量中。同时为了避免错误操作,JavaScript解释器强制约定字符串在堆区存储的数据是不可变的。这相当于设置字符串在堆区存储的数据为“只读”内容。因此,我们会发现没有一种JavaScript语法、方法或属性可以改变字符串中的原字符。
当进行字符串的复制和传递时,只是在栈区复制和传递字符串的引用地址,这种模拟使用引用的方法进行操作加快了内存的计算速度,不必把所有字符串都读取到栈区进行操作,这样节省了大量时间,提高了运行效率。
例如,把变量a中的字符串复制给变量b,那么在b中修改字符串内容,不会影响到a中包含的内容,字符串的复制和传递操作像是为字符串建立了独立的副本。

  1. var a = "javascript";
  2. var b = a;
  3. bb = b.toUpperCase();
  4. alert(a);
  5. alert(b);
    在上面代码中,最终变量a和b的值是不同的,虽然它们都引用同一个字符串。JavaScript对于字符串的复制和传递仅是简单地采用引用的方法,操作对象为堆区字符串的地址,即复制和传递地址。但是,一旦编辑字符串本身的值, JavaScript就会把堆区的字符串读取到栈区进行独立操作。

操作完毕,要把结果赋值给原变量,JavaScript需要再次把字符串数据写回堆区,但没有覆盖原值所在的区域,而是新开辟一个区域进行存储,并把新空间的地址传递给栈区的变量进行存储,也就是说,在堆区新建一个副本。如果不把结果赋值给变量,就待在栈区等待JavaScript垃圾回收,而原来变量的值并没有改变。所以,在上面代码中,修改变量b的字符串后,还要把结果字符串赋值给变量b。用示意图进行演示。

因此,在操作字符串时,读者应该注意以下问题:
字符串的复制(即赋值)、传递(参数传递)仅是对字符串的引用进行操作,而不是对字符串本身的值进行操作。
修改字符串的值,需要使用值的方法进行操作,而不用修改对字符串的引用。
修改字符串的值,不是在堆区原值本身上进行修改,而是通过副本进行修改。
修改的字符串副本与原值没有任何联系,如果不把修改值复制给原值变量,则不会对原值产生影响。
当把修改的字符串复制给原值变量时,会重新建立一个新的引用,并把修改值存储到堆区新的位置。
原值引用的区域,如果还被其他变量引用,则继续保留,否则会被JavaScript回收程序回收。

网友评论

登录后评论
0/500
评论