怎么理解ECMAScript中的字符串是不可变的?
JavaScript高级程序设计的第33页中提到:ECMAScript中的字符串是不可变的,然后给出了下面的示例。
var lang = "Java";
lang = lang + "Script";
第二行中赋值号左边的
lang
不就是第一行中定义的
lang
吗,然后给它赋了新的值不就改变了这个字符串吗。可上面又写到ECMAScript中的字符串是不可变的,这怎么理解?
Answers
/* String 不可变 */
var lang = 'Java';
undefined
lang[lang.length] = 'S';
"S"
lang[lang.length] = 'c';
"c"
lang[lang.length] = 'r';
"r"
lang[lang.length] = 'i';
"i"
lang[lang.length] = 'p';
"p"
lang[lang.length] = 't';
"t"
lang
"Java"
/* Array 可变 */
var arr = ['J', 'a', 'v', 'a']
undefined
arr[arr.length] = 'S';
"S"
arr[arr.length] = 'c';
"c"
arr[arr.length] = 'r';
"r"
arr[arr.length] = 'i';
"i"
arr[arr.length] = 'p';
"p"
arr[arr.length] = 't';
"t"
arr
["J", "a", "v", "a", "S", "c", "r", "i", "p", "t"]
像是js,以及c#等一系列的语言,推出任何一个特征都要和c比一比,你知道的:)。
string的不可变性也是一样,你看:
- C的string是可以改变的。
你可以
char str[] = "Foo";
str[0] = ‘G'
str的内容确实被改变了。可以通过print来证明。打印内容,也打印指针。指针不变,内容变了。
2.js的不可改.如下的代码,没有任何效果,也可以log出来证明
var str = "foo";
str[0] = 'g' ;
因为,语义上来说,这样做意味着原位修改str的内存区内容
- 但是你可以
var str = "foo";
var = 'bar'
因为原位置的内存没有修改,是新分配的。只是打印不了指针,不好直接证明。要么就看代码,那就啰嗦了。非常非常的啰嗦。
至于好处吗,和性能、存储效率、引用计数有关。
所以,我就不讲了。
javascript中明确规定了原始值(null、undefined、数值、布尔值、字符串)的值是不可改变的,这里的不可改变是指改变字符串本身在js中是禁止操作的。也就是说每新建一个字符串,都会开辟一块新的内存:
var lang = 'java';
lang = lang +'Script';
假设保存第一行字符串的地址是A,第二行的地址是B;字符串不可改变的意思就是:执行第二条语句的时候,是新建一个字符串('java'+'Script'),然后将原来指向A的lang改为指向新的地址,即B,若字符串可以修改,那么此时应该是修改原来A地址中的值为javaScript,但是这样在js中是禁止的,所以说字符串是不可修改的。
/* String 不可变 */
var lang = 'Java';
undefined
lang[lang.length] = 'S';
"S"
lang[lang.length] = 'c';
"c"
lang[lang.length] = 'r';
"r"
lang[lang.length] = 'i';
"i"
lang[lang.length] = 'p';
"p"
lang[lang.length] = 't';
"t"
lang
"Java"
/* Array 可变 */
var arr = ['J', 'a', 'v', 'a']
undefined
arr[arr.length] = 'S';
"S"
arr[arr.length] = 'c';
"c"
arr[arr.length] = 'r';
"r"
arr[arr.length] = 'i';
"i"
arr[arr.length] = 'p';
"p"
arr[arr.length] = 't';
"t"
arr
["J", "a", "v", "a", "S", "c", "r", "i", "p", "t"]
javascript中明确规定了原始值(null、undefined、数值、布尔值、字符串)的值是不可改变的,这里的不可改变是指改变字符串本身在js中是禁止操作的。也就是说每新建一个字符串,都会开辟一块新的内存:
var lang = 'java';
lang = lang +'Script';
假设保存第一行字符串的地址是A,第二行的地址是B;字符串不可改变的意思就是:执行第二条语句的时候,是新建一个字符串('java'+'Script'),然后将原来指向A的lang改为指向新的地址,即B,若字符串可以修改,那么此时应该是修改原来A地址中的值为javaScript,但是这样在js中是禁止的,所以说字符串是不可修改的。
像是js,以及c#等一系列的语言,推出任何一个特征都要和c比一比,你知道的:)。
string的不可变性也是一样,你看:
- C的string是可以改变的。
你可以
char str[] = "Foo";
str[0] = ‘G'
str的内容确实被改变了。可以通过print来证明。打印内容,也打印指针。指针不变,内容变了。
2.js的不可改.如下的代码,没有任何效果,也可以log出来证明
var str = "foo";
str[0] = 'g' ;
因为,语义上来说,这样做意味着原位修改str的内存区内容
- 但是你可以
var str = "foo";
var = 'bar'
因为原位置的内存没有修改,是新分配的。只是打印不了指针,不好直接证明。要么就看代码,那就啰嗦了。非常非常的啰嗦。
至于好处吗,和性能、存储效率、引用计数有关。
所以,我就不讲了。