JavaScript 字符串
字符串是表示文本的数据类型。网页上的所有文字、用户输入、API 返回的内容,基本都是字符串。这一章我们学习字符串的创建、查找、截取、替换、转换,重点掌握现代 JS 的模板字符串和常用的字符串方法。
1. 字符串与模板字符串
JS 字符串可以用单引号、双引号、反引号三种方式包裹。前两种几乎完全一样,反引号是 ES6 引入的模板字符串,功能更强大:
// 三种引号
const a = "双引号";
const b = '单引号';
const c = `反引号`;
// 模板字符串(反引号)的两大优势:
// 1. 嵌入变量和表达式:用 ${}
const name = "小明";
const age = 20;
const greeting = `你好,${name}!明年你 ${age + 1} 岁。`;
console.log(greeting);
// 输出: 你好,小明!明年你 21 岁。
// 2. 支持多行(单双引号不行)
const html = `<div>
<h1>${name}</h1>
<p>年龄:${age}</p>
</div>`;
console.log(html);
// 转义字符:反斜杠
console.log("换行\n 制表符\t 引号\" 反斜杠\\");模板字符串的两个核心优势:多行书写和嵌入表达式。现代 JS 中,需要拼接变量或多行文本时一律用反引号,告别 + 号拼接的繁琐。
2. 字符串是不可变的
字符串一旦创建,内容不能被修改。所有"修改"操作(如 replace、toUpperCase)都会返回新字符串,原字符串不变:
let s = "hello";
s[0] = "H"; // ⚠️ 无效!不会报错,但也没改变 s
console.log(s); // "hello"
// 想改只能重新赋值
s = "H" + s.slice(1);
console.log(s); // "Hello"
// 或者用 replace
s = s.replace("H", "h");
console.log(s); // "hello"3. 查找子串
// 查找子串
const str = "Hello, JavaScript!";
// indexOf:首次出现的位置(不存在返回 -1)
console.log(str.indexOf("Java")); // 7
console.log(str.indexOf("Python")); // -1
// lastIndexOf:最后一次出现的位置
console.log("a-b-c-d".lastIndexOf("-")); // 5
// includes:是否包含(ES6,最直观)
console.log(str.includes("Java")); // true
console.log(str.includes("java")); // false(区分大小写)
// startsWith / endsWith:是否以某串开头/结尾
console.log(str.startsWith("Hello")); // true
console.log(str.endsWith("!")); // true
// 大小写无关的查找
console.log(str.toLowerCase().includes("java")); // trueincludes 是 ES6 引入的,语义最直观,日常开发优先用。需要知道位置时才用 indexOf。注意所有查找都区分大小写,需要忽略大小写就先 toLowerCase() 或用正则。
4. 截取子串
// 截取子串
const str = "Hello, World!";
// slice(起始, 结束):最推荐,支持负数
console.log(str.slice(7, 12)); // "World"(不含 end)
console.log(str.slice(7)); // "World!"(到末尾)
console.log(str.slice(-6, -1)); // "World"(负数从末尾算)
// substring(起始, 结束):类似 slice,但负数会变 0
console.log(str.substring(7, 12)); // "World"
// substr(起始, 长度):已废弃,不推荐
console.log(str.substr(7, 5)); // "World"
// charAt / charCodeAt
console.log(str.charAt(0)); // "H"
console.log(str.charCodeAt(0)); // 72(ASCII)
console.log(str[0]); // "H"(也可以,但越界返回 undefined)三个截取方法,记住 slice 就够了——它支持负数(从末尾算),行为最直观。substr 已被废弃,新代码不要用。
5. 大小写、空白、替换
const str = "Hello World";
// 大小写
console.log(str.toUpperCase()); // "HELLO WORLD"
console.log(str.toLowerCase()); // "hello world"
// trim():去掉首尾空白(常用!)
console.log(" hi ".trim()); // "hi"
console.log(" hi ".trimStart()); // "hi "(只去首部)
console.log(" hi ".trimEnd()); // " hi"
// repeat():重复
console.log("ab".repeat(3)); // "ababab"
// padStart / padEnd:补齐到指定长度(格式化数字时超有用)
console.log("5".padStart(3, "0")); // "005"
console.log("123".padEnd(6, "*")); // "123***"
// replace / replaceAll:替换
console.log("hello".replace("l", "L")); // "heLlo"(只换第一个)
console.log("hello".replaceAll("l", "L")); // "heLLo"(换所有,ES2021)trim 处理用户输入时几乎是必备——用户经常不小心多打个空格。padStart 在格式化数字(如日期、月份补零)时极其好用。
6. split 与 join
split 和 join 是字符串与数组之间的双向桥梁:
// split:字符串 → 数组(超常用)
const csv = "苹果,香蕉,樱桃";
const fruits = csv.split(",");
console.log(fruits); // ["苹果","香蕉","樱桃"]
// 按空格切
console.log("hello world js".split(" "));
// ["hello","world","js"]
// 切成字符数组
console.log("abc".split(""));
// ["a","b","c"]
// 限制元素数量
console.log("1-2-3-4".split("-", 2));
// ["1","2"]
// 反向:join 把数组拼成字符串
console.log(["a", "b", "c"].join("-")); // "a-b-c"
// 实战:URL 参数解析
const url = "name=小明&age=20";
const params = Object.fromEntries(
url.split("&").map(pair => pair.split("="))
);
console.log(params); // { name: "小明", age: "20" }日常处理 CSV、URL 参数、分隔符数据,基本套路就是 split 成数组、操作、join 回字符串。
7. 字符串与正则表达式
JS 的正则表达式用 /模式/标志 写。字符串方法可以配合正则,实现复杂的匹配和替换:
// 字符串方法 + 正则
const str = "Hello 123 World 456";
// match:匹配
const nums = str.match(/\d+/g);
console.log(nums); // ["123","456"]
// replace + 正则:全局替换
const result = str.replace(/\d+/g, "数字");
console.log(result); // "Hello 数字 World 数字"
// test:测试是否匹配
console.log(/\d/.test("abc")); // false
console.log(/\d/.test("a1")); // true
// 实战:校验手机号(简单版)
function isPhone(s) {
return /^1\d{10}$/.test(s);
}
console.log(isPhone("13812345678")); // true
console.log(isPhone("12345")); // false
// 实战:邮箱简单校验
function isEmail(s) {
return /^[^@]+@[^@]+\.[^@]+$/.test(s);
}正则是另一门大学问,这里只做入门。日常用得最多的场景是校验格式(手机号、邮箱、身份证)和批量替换。深入推荐看 MDN 正则教程。
8. 字符串与数字转换
// 字符串 ↔ 数字 转换
// 字符串 → 数字
console.log(Number("42")); // 42
console.log(Number("42.5")); // 42.5
console.log(Number("")); // 0
console.log(Number("abc")); // NaN
console.log(parseInt("42px")); // 42(整数,会忽略小数点)
console.log(parseInt("3.99")); // 3
console.log(parseFloat("3.14abc")); // 3.14
console.log(+"42"); // 42(最简写法)
console.log(Math.floor("3.99")); // 3
// 数字 → 字符串
console.log(String(42)); // "42"
console.log((42).toString()); // "42"
console.log((3.14159).toFixed(2)); // "3.14"(保留 2 位小数)
console.log((1234.5).toLocaleString()); // "1,234.5"(千分位)parseFloat vs parseInt:前者保留小数,后者只取整数。Number vs parseInt:前者对非数字字符串返回 NaN,后者会"解析到第一个非数字字符"。
9. 编码与 Unicode
// JS 字符串内部是 UTF-16 编码
const cn = "你好";
console.log(cn.length); // 2(两个字符)
console.log(cn.charCodeAt(0)); // 20320(Unicode 码点)
// 从码点创建字符
console.log(String.fromCharCode(20320)); // "你"
// 注意 emoji 是"代理对",length 不准
const emoji = "😀";
console.log(emoji.length); // 2(实际是 1 个字符!)
console.log([...emoji].length); // 1(用展开运算符获取真长度)
// Base64 编解码(浏览器内置)
const encoded = btoa("Hello"); // "SGVsbG8="
console.log(encoded);
console.log(atob(encoded)); // "Hello"处理 emoji、特殊符号时,要小心 length、split("")、charAt 都可能不准。安全做法是用 [...str] 或 Array.from(str) 转成"字符数组"。
10. 实战示例
// 1. 驼峰转下划线
function camelToSnake(s) {
return s.replace(/[A-Z]/g, ch => "_" + ch.toLowerCase());
}
console.log(camelToSnake("userName")); // "user_name"
console.log(camelToSnake("getUserInfo")); // "get_user_info"
// 2. 下划线转驼峰
function snakeToCamel(s) {
return s.replace(/_([a-z])/g, (_, ch) => ch.toUpperCase());
}
console.log(snakeToCamel("user_name")); // "userName"
// 3. 金额格式化:1234.5 → "1,234.50"
function formatMoney(n) {
return n.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(formatMoney(1234.5)); // "1,234.50"
// 4. 截断长文本
function truncate(str, max) {
return str.length > max ? str.slice(0, max - 1) + "…" : str;
}
console.log(truncate("hello world", 8)); // "hello w…"小结
- 字符串不可变,所有操作返回新字符串。
- 模板字符串(反引号)支持多行和嵌入表达式。
- 查找:优先
includes;位置用indexOf。 - 截取:用
slice(支持负数)。 - 字符串 ↔ 数组转换:
split/join。 - 校验和复杂替换用正则。
下一篇进入浏览器世界——DOM 操作,让 JS 真正能"动网页"。
← 上一篇 JavaScript 数组
下一篇 JavaScript DOM 操作 →