我今天再次阅读我的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'
我在这里搜索了堆栈溢出和谷歌,我发现了一些谈论这个的文章,但大多数文章都在讨论其他语言,如Java和C#。
问题: 在javascript中,字符串被认为是原始的或引用变量类型,还有其他任何情况我应该知道字符串的工作方式与我期望的不同吗?
答案 0 :(得分:2)
执行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程序完全不透明的实现细节。)
答案 1 :(得分:2)
没有。在JavaScript中,字符串是不可变的,因此是基本类型。
它们具有可变大小就像不同大小的数字一样。它们的大小不是动态,您无法更改现有字符串值的大小。无论何时进行字符串操作,都要创建新值。就像var x = 1; x += 2
无法更改1
值(但创建新的3
值)一样,var var a = "Hi!"; a += "!"
无法更改字符串"Hi!"
}。
答案 2 :(得分:0)
在JavaScript中,字符串是原语。
但是,有一件事你应该是可以理解的。 Wraper对象。像字符串,数字,布尔值这样的原语被包装在对象中,所以你可以在这些包装器对象上调用属性,以便进行检测:var foo = 'bar';
var poo = foo.slice(0,-1)
poo == 'ar'; //true
这里是字符串' bar'包含在具有切片方法(以及许多其他方法)的对象中,但在所有其他情况下(当您只是传递原始变量等)时,变量只是一个原语。
答案 3 :(得分:0)
示例3不起作用,因为正如Jordan所说,如果更改实际对象的值而不仅仅是属性,则对象指向的对象将不会更改,即使对象是JavaScript中的引用类型。
但是,字符串是不可变的和原始值,所以即使我们做了类似的事情:
var a = "Hi!";
var b = a;
a[2] = "?";
alert(a);
alert(b);
a
仍然是"Hi!"
,因为字符串是不可变的,b
即使"Hi!"
是a
仍然是"Hi?"
,因为字符串是原始价值观。