我今天又在看我的javascript书,它解释了引用类型变量和基本类型变量之间的区别。文中给出了这些例子来说明两者的区别。
示例1(基本类型)var a = 3.14;
var b = a;
a = 4;
alert( b ); // Displays 3.14
例2(引用类型)
var a = [1, 2, 3];
var b = a;
var a[0] = 99;
alert( b ); // Displays the changed array [99, 2, 3]
我明白这个例子,我没有任何问题。我的问题是关于javascript中的字符串。直观地,我会假设字符串是引用类型变量,因为它是动态大小,但我在example.com上摆弄它们,我创建了这个例子,似乎表明字符串是基本类型变量。
示例3(字符串?)
var a = 'Ben';
var b = a;
var a = 'Benjamin';
alert( b ); //Displays the unchanged 'Ben'
我在这里搜索了一下stack overflow和google,我发现了一些讨论这个问题的文章,但大多数都是在讨论其他语言,比如Java和c#。
问题:在javascript中字符串被认为是原始或引用变量类型,是否有任何其他情况,我应该知道在哪里字符串的工作方式不同,然后我期望?
No。在JavaScript中,字符串是不可变的,因此是基本类型。
它们有不同的大小,就像不同大小的数字一样。它们的大小不是动态,您不能更改现有字符串值的大小。无论何时执行字符串操作,都是在创建新值。就像var x = 1; x += 2
不会改变1
的值(但会创建一个新的3
值),var var a = "Hi!"; a += "!"
不会改变字符串"Hi!"
。
当您执行a = 'Benjamin'
时,赋值操作符(=
)会更改a
所指向的对象。它不会改变其他变量指向的对象。说明:
var a, b;
a = "Ben"; // `a` now points to "Ben" in memory
b = a; // `b` now points to "Ben" in memory
a = "Benjamin"; // `a` now points to "Benjamin" in memory, but
// `b` still points to "Ben"
这与字符串没有什么特别的关系;语义对于任何原语或对象值都是相同的。
正如Bergi所指出的那样,你的问题的答案的一个重要部分是,JavaScript中的字符串是不可变的,因此无论实现如何,它们本质上都是原语。再一次,为了说明:
a = "Ben"; // `a` now points to "Ben" in memory
b = a; // `b` now points to "Ben" in memory
a += "jamin"; // `a` now points to "Benjamin" in memory, but
// `b` still points to "Ben"
a += "jamin"
,如你所知,相当于a = a + "jamin"
,不会改变a
和b
指向的字符串;它创建一个值为"Benjamin"
的新字符串,并使a
指向它而不是"Ben"
。("Ben"
和"Benjamin"
是否在内存中共享相同的字节是一个实现细节,对JavaScript程序来说是完全不透明的。)
在JavaScript中字符串是原语。
但是,有一件事你应该注意。包装对象。像字符串、数字、布尔值这样的原语被包装在对象中,因此您可以在这些包装对象上调用属性,例如:var foo = 'bar';
var poo = foo.slice(0,-1)
poo == 'ar'; //true
这里字符串'bar'被包装在对象中,对象有slice方法(和许多其他方法),但在所有其他情况下(当你只是传递原始变量等),变量只是一个原始的。
示例3不起作用,因为正如Jordan所说,如果您更改实际对象的值而不仅仅是属性,那么object所指向的对象将不会更改,即使object在JavaScript中是引用类型。
然而,字符串是不可变的基本值,所以即使我们这样做:
var a = "Hi!";
var b = a;
a[2] = "?";
alert(a);
alert(b);
a
仍然是"Hi!"
,因为字符串是不可变的,即使a
是"Hi?"
, b
仍然是"Hi!"
,因为字符串是基本值。