返回

JS的字符串之于数组,巧合还是设计?

前端

诸位在打字的时候,是不是经常遇到这样的问题?输入框文本内容要截取特定字符后几位的字符,Copy操作后,正想狂按Delete来“剪掉”要保留的部分文本内容。此时是不是会因为对“数组”和“字符串”概念混淆而导致操作失误呢?

相信在编程的道路上,经常会遇到用JavaScript处理字符串的场景,很多时候,JavaScript字符串与数组的相似性都会为我们带来方便,但两者之间在本质上有什么区别呢?今天我们来聊一聊。

字符串与数组:巧合的相似

在 JavaScript 中,字符串和数组都属于对象,它们都具有 length 属性,并且都支持类似数组的方法,例如 concat(), indexOf(), lastIndexOf(), slice(), splice(), substring()substr(), toLowerCase(), toUpperCase(), trim(), charAt(), charCodeAt()fromCharCode()

通过运行下面的JavaScript代码可以得到两种对象的演示:

const str = "Hello World!";
const arr = [1, 2, 3, 4, 5];

console.log(str.length); // 12
console.log(arr.length); // 5

console.log(str.concat("!")); // "Hello World!"
console.log(arr.concat([6])); // [1, 2, 3, 4, 5, 6]

console.log(str.indexOf("W")); // 6
console.log(arr.indexOf(3)); // 2

console.log(str.lastIndexOf("o")); // 7
console.log(arr.lastIndexOf(3)); // 2

console.log(str.slice(2, 5)); // "llo"
console.log(arr.slice(1, 3)); // [2, 3]

console.log(str.splice(2, 0, "!")) ; // "He!llo World!"
console.log(arr.splice(1, 2, 6, 7)); // [1, 6, 7, 4, 5]

console.log(str.substring(2, 5)); // "llo"
console.log(arr.substring(1, 3)); // undefined

console.log(str.substr(2, 3)); // "llo"
console.log(arr.substr(1, 3)); // undefined

console.log(str.toLowerCase()); // "hello world!"
console.log(arr.toLowerCase()); // TypeError: arr.toLowerCase is not a function

console.log(str.toUpperCase()); // "HELLO WORLD!"
console.log(arr.toUpperCase()); // TypeError: arr.toUpperCase is not a function

console.log(str.trim()); // "Hello World!"
console.log(arr.trim()); // TypeError: arr.trim is not a function

console.log(str.charAt(2)); // "l"
console.log(arr.charAt(2)); // TypeError: arr.charAt is not a function

console.log(str.charCodeAt(2)); // 108
console.log(arr.charCodeAt(2)); // TypeError: arr.charCodeAt is not a function

console.log(String.fromCharCode(108)); // "l"
console.log(Array.fromCharCode(108)); // TypeError: Array.fromCharCode is not a function

字符串与数组:本质的区别

即使字符串和数组具有惊人的相似性,但这并不意味着它们是同一回事。字符串是不可变的,这意味着一旦创建了字符串,就不能对其内容进行更改。例如,以下代码将创建一个新的字符串,但不会更改原始字符串:

const str = "Hello World!";
str.toUpperCase(); // "HELLO WORLD!"
console.log(str); // "Hello World!"

数组是可变的,这意味着可以对其内容进行更改。例如,以下代码将修改原始数组:

const arr = [1, 2, 3, 4, 5];
arr.push(6);
console.log(arr); // [1, 2, 3, 4, 5, 6]

为何JavaScript如此设计?

字符串和数组在JavaScript中如此设计的原因有很多。首先,它允许 JavaScript 具有更简洁的语法。如果字符串和数组是完全不同的对象,那么我们就需要更多的方法来处理它们。例如,我们需要一个方法来从字符串中获取字符,另一个方法来从数组中获取元素。

其次,它允许 JavaScript 更高效地处理字符串和数组。由于字符串和数组在内部表示上非常相似,因此 JavaScript 可以在它们之间进行快速转换。这使得 JavaScript 非常适合处理大量文本数据。

小贴士

最后分享一个JavaScript中字符串与数组之间的一个有趣小技巧:

const str = "Hello World!";
const arr = str.split(""); // ["H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d", "!"]

调用 split() 函数后,字符串被转换成一个由字符串中的每个字符组成的数组。这可以用来将字符串拆分为更小的部分,以便进行处理。