简体   繁体   English

字符串:javascript中的原始类型变量或引用类型变量?

[英]Strings: Primitive type variables or reference type variables in javascript?

I was reading in my javascript book again today and it was explaining the difference between reference type variables and primitive type variables. 我今天再次读了我的JavaScript书,它解释了引用类型变量和原始类型变量之间的区别。 It gave these examples to illustrate the difference. 它给出了这些例子来说明差异。

Example 1 (Primitive Type) 示例1(原始类型)

var a = 3.14;
var b = a;
a = 4;
alert( b ); // Displays 3.14

Example 2 (Reference Type) 示例2(引用类型)

var a = [1, 2, 3];
var b = a;
var a[0] = 99;
alert( b ); // Displays the changed array [99, 2, 3]

I understand this example and I don't have any questions about it. 我理解此示例,对此没有任何疑问。 My question is about strings in javascript. 我的问题是关于javascript中的字符串。 Intuitively, I would assume that strings are reference type variables because if the dynamic size, but I was messing around with them on example.com and I created this example which seems to indicate that strings are primitive type variables. 凭直觉,我会假设字符串是引用类型变量,因为如果使用动态大小,但是我在example.com上弄乱了它们,我创建了这个示例,该示例似乎表明字符串是原始类型变量。

Example 3 (Strings?) 示例3(字符串?)

var a = 'Ben';
var b = a;
var a = 'Benjamin';
alert( b ); //Displays the unchanged 'Ben'

I've searched around here on stack overflow and on google and I found a few articles that talked about this but most of them were talking about other languages such as Java and C#. 我在这里搜索了堆栈溢出和google,并发现了一些有关此的文章,但大多数文章都在谈论其他语言,例如Java和C#。

Question: In javascript are Strings considered primitive or reference variable types and are there any other situations that I should be aware of where Strings work differently then I would expect? 问题: 在javascript中,字符串是否被视为原始或引用变量类型,还有其他情况我应该知道字符串的工作方式与我期望的不同吗?

When you do a = 'Benjamin' , the assignment operator ( = ) changes the object to which a points. 当你做a = 'Benjamin' ,赋值运算符( = )更改对象到a点。 It does not change to what object other variables point. 它不会更改为其他变量指向的对象。 To illustrate: 为了显示:

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" 

This isn't anything special to do with strings; 这与字符串没什么特别的。 the semantics are the same for any primitive or object value. 任何原始值或对象值的语义都是相同的。

An important part of the answer to your question is, as Bergi points out, that strings in JavaScript are immutable, and so regardless of implementation they act, essentially, as primitives. 正如贝吉指出的那样,您问题的答案的重要组成部分是JavaScript中的字符串是不可变的,因此,无论它们如何实现,它们本质上都充当原语。 Again, to illustrate: 再次说明一下:

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" , which as you know is equivalent to a = a + "jamin" , doesn't change the string that a and b point to; 您知道, a += "jamin"等效于a = a + "jamin" ,它不会更改ab指向的字符串; it creates a new string with the value "Benjamin" and makes a point to it instead of "Ben" . 它将创建一个具有价值的新字符串"Benjamin" ,使a指向它,而不是"Ben" (Whether or not "Ben" and "Benjamin" share any of the same bytes in memory is an implementation detail that is completely opaque to the JavaScript program.) "Ben""Benjamin"共享内存中的任何相同字节都是对JavaScript程序完全不透明的实现细节。)

No. In JavaScript, strings are immutable , and therefore a primitive type. 不可以。在JavaScript中,字符串是不可变的 ,因此是基本类型。

That they have variable sizes is just like numbers of different magnitude. 它们具有可变的大小,就像大小不同的数字一样。 Their size is not dynamic , you cannot change the size of an existing string value. 它们的大小不是动态的 ,您不能更改现有字符串值的大小。 Whenever you do string operations, you are creating new values. 每当您执行字符串操作时,都将创建新值。 Just like var x = 1; x += 2 就像var x = 1; x += 2 var x = 1; x += 2 won't change the 1 value (but create a new 3 value), var var a = "Hi!"; a += "!" var x = 1; x += 2不会更改1值(而是创建一个新的3值), var var a = "Hi!"; a += "!" var var a = "Hi!"; a += "!" won't change the string "Hi!" 不会更改字符串"Hi!" .

In JavaScript strings are primitives. 在JavaScript中,字符串是基元。

There is a thing you should be avare of, though. 不过,您应该拥有一件事。 Wraper objects. 包装对象。 primitives like strings, numbers, booleans get wrapped up in objects, so you can call properties on these wrapper objects, for insance: 诸如字符串,数字,布尔值之类的基元被包装在对象中,因此您可以在这些包装器对象上调用属性,例如:

var foo = 'bar';
var poo = foo.slice(0,-1)
poo == 'ar'; //true

Here string 'bar' is wrapped up in object that has slice method ( and many others ), but in all other cases ( when you just pass primitive variables around, etc. ) the variable is just a primitive. 在这里,字符串“ bar”被包装在具有slice方法(以及许多其他方法)的对象中,但是在所有其他情况下(当您仅传递原始变量时,等等),该变量只是一个原始变量。

Example 3 doesn't work because, as Jordan said, if you change the value of an actual object and not just a property, the objects that object point to won't change even though object is a reference type in JavaScript. 示例3无效,因为正如Jordan所说,如果您更改实际对象的值而不仅仅是属性,则即使Object是JavaScript中的引用类型,该对象所指向的对象也不会更改。

However, strings are immutable and primitive values, so even if we did something like this: 但是,字符串是不可变的且是原始值,因此即使我们执行以下操作:

var a = "Hi!";
var b = a;
a[2] = "?";
alert(a);
alert(b);

a would still be "Hi!" a仍然是"Hi!" because strings are immutable and b would still be "Hi!" 因为字符串是不可变的,并且b仍然是"Hi!" even if a was "Hi?" 即使a"Hi?" because strings are primitive values. 因为字符串是原始值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM