2024年4月20日
通过本文提升您对 JavaScript 字符串的了解!
一篇关于 JavaScript 中字符串如何工作的简短文章。它涵盖了字符串的不变性、比较机制以及字符串的内存分配优化。
让我们从一些问题开始:这段代码会输出什么?
const str = "Hello";
str[2] = "a";
console.log(str);
如果我们将 const
替换为 let
会怎样?
let str = "Hello";
str[2] = "a";
console.log(str);
尝试将这段代码输入到您的浏览器控制台中,看看会发生什么。
在 JavaScript 中,字符串是不可变的。这意味着无论变量是用 let
还是 const
声明的,值都不会改变,在这两种情况下,都会输出 "Hello"。
但是如果我们添加一个带有字符串连接的赋值运算符:
const str = "Hello";
str += " World";
console.log(str);
这段代码将导致 TypeError: Assignment to constant variable
,因为我们将字符串声明为 const
。让我们将其更改为 let
:
let str = "Hello";
str += " World";
console.log(str);
在 JavaScript 中,当从一个字符串向另一个字符串赋值时,字符串会被复制。因此,这段代码将输出 "Hello World"。在文章的结尾,我们将逐步解释这样的代码是如何工作的。
让我们更深入地研究字符串复制。这段代码会输出什么,为什么?
const str1 = "Hello";
const str2 = str1;
console.log(str1 === str2);
在 JavaScript 中复制字符串时,会为字符串对象创建一个新的引用,但字符串本身不会在内存中被复制。因此,当比较 str1 === str2
时,将输出 true
。以下是详细说明:
- 创建字符串
'Hello'
:为存储字符串'Hello'
分配内存。 - 向另一个变量赋值:变量
str2
获得与变量str1
相同的内存中字符串对象的引用。 - 变量比较:在比较
str1 === str2
时,JavaScript 首先比较引用值,而不是字符串本身。由于两个变量引用内存中的同一个字符串对象,比较将返回true
。
但是如果我们不复制字符串,而是创建一个与第一个相同值的新字符串会怎样?这段代码会输出什么,为什么,它是如何工作的?
const str1 = "Hello";
const str2 = "Hello";
console.log(str1 === str2);
- 当声明
const str1 = 'Hello'
时,为存储字符串'Hello'
分配内存。 - 然后,当声明
const str2 = 'Hello'
时,JavaScript 优化内存使用,并为两个变量只创建一个字符串对象。JavaScript 检测到字符串'Hello'
已经存在于内存中(由于声明str1
的结果),而不是为字符串'Hello'
分配新的内存,只为变量str2
创建对这个相同字符串的引用。 - 当执行
console.log(str1 === str2)
时,比较变量str1
和str2
。由于两个变量引用内存中的同一个字符串对象,比较将返回true
。
现在,让我们更详细地研究字符串的连接:
const str1 = "Hello";
const str2 = str1 + "2";
console.log(str1 === str2);
- 当声明
const str1 = 'Hello'
时,为字符串'Hello'
分配内存。 - 当声明
const str2 = str1 + '2'
时,发生字符串连接。JavaScript 通过组合str1
的内容(包含'Hello'
)和字符串'2'
创建一个新字符串。由于 JavaScript 中的字符串是不可变的,为连接结果创建了一个新的字符串对象,在这种情况下是'Hello2'
。 - 当执行
console.log(str1 === str2)
时,由于str1
包含'Hello'
,而str2
包含'Hello2'
,它们指向内存中的不同字符串对象,比较将返回false
。