为何String.concat结合apply使用未达预期?如何正确调用?
解决字符串/数组作为上下文时的concat.apply拼接问题
看起来你是混淆了数组的concat方法和字符串的concat方法的作用,才导致出现元素缺失、自动插入逗号的问题——当你把数组作为apply的第一个参数(也就是this上下文)时,调用的其实是Array.prototype.concat,它的作用是合并数组而非拼接字符串,最终得到的数组在隐式转换为字符串时会自动用逗号分隔元素;而如果错误地把数组传给String.prototype.concat的this,数组本身会被转换成逗号分隔的字符串,自然不符合你的拼接需求。
针对你「第一个参数可能是字符串或数组」的场景,这里有几种正确的实现方式:
方法1:统一转为数组后拼接(最简洁)
不管输入是字符串还是数组,我们先把它转为数组,合并所有需要拼接的内容后,用join('')直接拼接成无分隔符的字符串:
function concatStrings(source, ...additionalParts) { // 将source转为数组:字符串包装成单元素数组,数组直接复用 const sourceArray = typeof source === 'string' ? [source] : source; // 合并所有待拼接的部分 const allParts = sourceArray.concat(...additionalParts); // 拼接成最终字符串 return allParts.join(''); } // 测试用例 console.log(concatStrings('hello', ['w', 'o', 'r', 'l', 'd'])); // 输出 "helloworld" console.log(concatStrings(['h', 'e', 'l'], ['l', 'o'])); // 输出 "hello"
方法2:用apply适配两种上下文(贴合你的需求)
如果你一定要用apply来实现,可以分情况处理上下文:
function concatWithApply(source, parts) { if (typeof source === 'string') { // source是字符串,直接用String.prototype.concat.apply return String.prototype.concat.apply(source, parts); } else if (Array.isArray(source)) { // source是数组,先合并source和parts,再用空字符串作为上下文调用concat.apply return String.prototype.concat.apply('', [...source, ...parts]); } } // 测试用例 console.log(concatWithApply('a', ['b', 'c', 'd'])); // 输出 "abcd" console.log(concatWithApply(['x', 'y'], ['z'])); // 输出 "xyz"
方法3:扁平化数组后拼接(一行代码搞定)
利用ES6的数组展开和flat()方法,可以一行代码实现通用拼接:
const result = [source, ...additionalParts].flat().join('');
flat()会自动将嵌套的数组扁平化,不管source是字符串还是数组,最终都会被展开为单个元素,再用join('')拼接成无分隔符的字符串。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

