为什么JS中Array.split拆分字符串仅返回前几个字符,末尾字符缺失?
JS代码字符串拆分后数组长度异常问题分析
核心原因
该现象和Array.isArray方法无关联,由两个JS语法特性共同导致:
Array.prototype.splice是原地修改方法,调用后会直接变更原数组的长度和内容- 浏览器
console.log打印数组、对象等引用类型时,存储的是内存引用,控制台展示的是代码全部执行完成后的最终状态,而非调用console.log时刻的快照。
运行逻辑拆解
代码执行流程如下:
- 传入字符串
"martin"时,Array.isArray("martin")返回false,调用split('')得到初始数组["m","a","r","t","i","n"],长度为6。 - 调用
map方法时,会先读取数组初始长度6作为遍历的索引上限,但遍历过程中如果对应索引的数组项不存在,将跳过回调执行。 - 每次回调执行
a.splice(-1)会删除数组最后一位元素,执行过程如下:- 索引0:删除元素
n,数组变为["m","a","r","t","i"],长度5 - 索引1:删除元素
i,数组变为["m","a","r","t"],长度4 - 索引2:删除元素
t,数组变为["m","a","r"],长度3 - 索引3、4、5:数组当前长度为3,对应索引无有效元素,回调直接跳过
- 索引0:删除元素
- 初始拆分得到的数组最终被修改为
["m","a","r"],console.log读取的是修改后的状态,因此看起来是split方法返回了不完整的数组。
验证方式
调整打印语句即可查看split的真实返回结果:
// 转成字符串存储当前快照 console.log(JSON.stringify(splittedStr)) // 浅拷贝新数组打印 console.log([...splittedStr])
修复方案
如果需要遍历过程不修改原数组,将splice替换为非原地修改的slice方法即可,示例如下:
let arrHelper = (str) => { let splittedStr = Array.isArray(str) ? str : str.split('') console.log(splittedStr) return splittedStr.map((v, i, a) => { // slice不会修改原数组,取对应位置的元素 return a.slice(a.length - 1 - i, a.length - i) }) }
如果需求是返回倒序的字符数组,可直接使用reverse方法:
let arrHelper = (str) => { let splittedStr = Array.isArray(str) ? [...str] : str.split('') return splittedStr.reverse() }
内容的提问来源于stack exchange,提问作者MARTIN GITAU
相关产品推荐
相关产品推荐

