优先用 slice:支持负索引、end 不包含、越界安全;substring 会交换参数顺序且负数转 0;substr 已废弃。includes 语义清晰判存在,indexOf 适合需索引的场景。trim 仅处理标准空白,全角等需正则。replace 字符串只替首处,全局须用 /g 正则。
slice、substring、substr 怎么选?三者都能取子串,但行为差异明显,容易出错:
slice(start, end) 支持负数索引(从末尾算),end 不包含,超出长度不报错返回空串substring(start, end) 会自动交换大小顺序(substring(3,1) 等价于 substring(1,3)),负数会被转为 0
substr(start, length) 已被废弃,length 是要取的字符数,不是结束位置;现代代码应避免使用推荐统一用 slice,语义清晰且兼容性好:
const str = "hello world"; str.slice(0, 5); // "hello" str.slice(-5); // "world" str.slice(100); // ""(安全)
includes 还是 indexOf?includes 更直观,返回布尔值;indexOf 返回索引,适合需要位置信息的场景:
"abc".includes("b") → true,语义明确,ES6+ 推荐"abc".indexOf("b") → 1,可用于后续操作(如从该位置继续查找)indexOf 在找不到时返回 -1,别误写成 != 0(这是常见 bug)str.toLowerCase().includes(search.toLowerCase())
trim 系列方法够用吗?trim() 只处理 Unicode 空白符(空格、制表、换行等),对全角空格、零宽字符、BOM 等无效:
" hello ".trim() → "hello"(正常)" hello ".trim()(全角空格)→ 仍保留首尾str.replace(/^[\\uFEFF\\u200B\\s]+|[\\uFEFF\\u200B\\s]+$/g, '')
trimStart() 和 trimEnd(),比 trimLeft/trimRight(已废弃)更规范replace 默认只换
第一个?replace 的第一个参数是字符串时,只替换首次出现;要全局替换必须用正则并加 g 标志:
"aabbcc".replace("b", "_") → "aa_bbcc"(仅第一次)"aabbcc".replace(/b/g, "_") → "aa__cc"(全部)new RegExp(pattern, 'g') 动态构造"123-456".replace(/\\d/g, m => +m + 1) → "234-567"
字符串方法看似简单,但边界行为(负索引、空输入、Unicode 字符、正则标志)最容易在上线后暴露问题。写完记得用中文、emoji、全角符号、空字符串多测几遍。