JavaScript 中将字符串转换为字符数组的 4 种方法
这里有四种方法可以将一个单词拆分成一个字符数组。“拆分”是最常见且更健壮的方法。但随着 ES6 的加入,JS 工具库中有了更多工具可供使用🧰
我总是喜欢看到解决问题的所有可能方法,因为这样你就可以根据你的用例选择最佳方法。而且,当你看到某个问题出现在别人的代码库中时,你就能轻松理解它了👍
const string = 'word';
// Option 1
string.split('');
// Option 2
[...string];
// Option 3
Array.from(string);
// Option 4
Object.assign([], string);
// Result:
// ['w', 'o', 'r', 'd']
场景
我不想讨论每种方法的优缺点,而是想向你展示不同场景下哪种方法更可取。
字符数组
如果你只是想用每个字符串字符分隔字符串,那么所有方法都是好的,并且会给你相同的结果
const string = 'hi there';
const usingSplit = string.split('');
const usingSpread = [...string];
const usingArrayFrom = Array.from(string);
const usingObjectAssign = Object.assign([], string);
// Result
// [ 'h', 'i', ' ', 't', 'h', 'e', 'r', 'e' ]
特定分隔符
如果您想按特定字符拆分字符串,那么这split
就是要走的方法。
const string = 'split-by-dash';
const usingSplit = string.split('-');
// [ 'split', 'by', 'dash' ]
其他方式仅受每个字符串字符的限制
const string = 'split-by-dash';
const usingSpread = [...string];
const usingArrayFrom = Array.from(string);
const usingObjectAssign = Object.assign([], string);
// Result:
// [ 's', 'p', 'l', 'i', 't', '-', 'b', 'y', '-', 'd', 'a', 's', 'h' ]
包含表情符号的字符串
如果你的字符串包含表情符号,那么split
或Object.assign
可能不是最佳选择。让我们看看会发生什么:
const string = 'cake😋';
const usingSplit = string.split('');
const usingObjectAssign = Object.assign([], string);
// Result
// [ 'c', 'a', 'k', 'e', '�', '�' ]
然而,如果我们使用其他方法,它就会起作用:
const usingSpread = [...string];
const usingArrayFrom = Array.from(string);
// Result
// [ 'c', 'a', 'k', 'e', '😋' ]
这是因为split
字符分隔符使用 UTF-16 编码,而 emoji 字符是 UTF-8 编码,这会带来问题。如果我们看一下 yum emoji,'😋'
它实际上是由两个字符组成的,而不是我们想象中的 1 个。
'😋'.length; // 2
这就是所谓的字素簇——用户感知到它是一个单一的单元,但实际上它是由多个单元组成的。较新的方法spread
可以Array.from
更好地处理这些问题,并会按字素簇拆分字符串👍
Object.assign
关于⚠️的警告
需要注意的Object.assign
是,它实际上不会生成纯数组。让我们从它的定义开始
Object.assign() 方法将所有可枚举的自身属性从一个或多个源对象复制到目标对象
这里的关键是“复制所有可枚举的自身属性”。所以我们在这里做的Object.assign([], string)
是将所有字符串属性复制到新数组中。这意味着我们有一个数组以及一些字符串方法。
TypeScript 测试:结果数组不是string[]
类型😱
如果我们使用 TypeScript Playgound,这一点会更加明显。您可以随意复制代码并粘贴到Playgound中,将鼠标悬停在变量上即可查看类型。由于这只是一篇文章,我将结果粘贴到这里,以便您跟进。
const word = 'word';
const usingSplit = string.split('');
const usingSpread = [...string];
const usingArrayFrom = Array.from(string);
// Result:
// string[] 👈 Which means it's an Array of strings
然而,如果我们看一下结果类型Object.assign
,它并没有给我们一个字符串数组。
const usingObjectAssign = Object.assign([], string);
// Result:
// never[] & "string" 👈 which means NOT Array of strings 😱
TypeScript 测试:结果数组可以访问字符串属性😱
我们可以通过访问仅适用于的属性来进一步检查这一点String
。
const string = 'string';
const array = [];
string.bold; // ✅(method) String.bold(): string
array.bold; // ❌Property 'bold' does not exist on type
这意味着如果我调用bold
我们的数组,它应该告诉我们这个属性不存在。这是我们期望看到的:
Array.from('string').bold;
// Property 'bold' does not exist on type
但是,如果我们调用bold
由创建的数组Object.assign
,它就会起作用😱
Object.assign([], 'string').bold;
// (method) String.bold(): string
☝️ 这是因为Object.assign
复制了原始字符串的所有属性。用非开发术语来说,我会这样解释。你去商店买狗。结果商店Object.assign
卖给你一只长着龙翅膀的狗。听起来很酷,但这可不是什么适合出租的宠物。嗯……我觉得这不是我最好的例子。不过我想你明白我的意思了😂
在浏览器中转换似乎没问题
现在我认为这不是一个重大的交易破坏者,因为:
看起来浏览器有某种机制来“安全地”执行 Object.assign([], "string") 并避免将该字符串的方法添加到数组中。
谢谢@lukeshiru:为我分享这些知识👏他还创建了一个 TypeScript 游乐场代码,以便你可以看到>链接
社区意见
[@CaptainOrion ]( https://twitter.com/captainorion_/status/1238979904567271425?s=21):_使用 map 函数将字符串转换为 char 数组🤣
Array.prototype.map.call('word', eachLetter => eachLetter);
// ['w', 'o', 'r', 'd']
@HiUmesh2 : Array.prototype.slice.call('string')
也会有效果
@inside.code:额外信息:使用扩展运算符(第二种方法)比String.prototype.split('')
(第一种方法)更安全,因为split()
它不适用于某些不常见的字符。
@faerberrr:我有一个包含特殊字符(例如“等”)的字符串。åæāă
当我使用该.split('')
方法拆分它们并运行 时.length
,它返回的值是预期值的两倍!切换到扩展运算符后,问题就解决了。
资源
- MDN Web 文档:拆分
- MDN Web 文档:传播
- MDN Web 文档:Array.from
- MDN Web 文档:Object.assign
- Stack Overflow:如何拆分字符串并在特定字符处断开?
- Stack Overflow:如何在 JavaScript 中将字符串转换为字符数组?
- Stack Overflow:如何将字符串拆分为字符数组?
- Stack Overflow:将 utf-8 转换为 Unicode,以便在 Java 字符串中查找表情符号
- 最初发表于 www.samanthaming.com
感谢阅读❤
打个招呼!Instagram | Twitter | SamanthaMing.com