三种字符串

const a = 'hello';
const b = "hello";
const c = `hello`;          // 模板字符串

模板字符串可以:

  • 跨多行
  • 嵌变量 / 表达式
const name = 'Alice';
const greeting = `Hello, ${name}!
Today is ${new Date().toDateString()}.
1 + 1 = ${1 + 1}`;

常用方法(字符串不可变,所有方法都返回新字符串)

大小写 / 修剪

'Hello'.toUpperCase()              // 'HELLO'
'Hello'.toLowerCase()              // 'hello'
'  hi  '.trim()                    // 'hi'
'  hi  '.trimStart()               // 'hi  '
'  hi  '.trimEnd()                 // '  hi'

查找

'hello world'.indexOf('world')     // 6(找不到返回 -1)
'hello world'.lastIndexOf('o')     // 7
'hello world'.includes('world')    // true
'hello'.startsWith('he')           // true
'hello'.endsWith('lo')             // true

提取

'hello'.slice(1, 3)                // 'el'
'hello'.slice(-2)                  // 'lo'
'hello'.substring(1, 3)            // 'el'
'hello'[1]                          // 'e'
'hello'.at(-1)                     // 'o'(Node 16+)

替换

'hello world'.replace('world', 'JS')      // 'hello JS'(只换第一个)
'aaa'.replaceAll('a', 'b')                 // 'bbb'(全部换,Node 15+)
'aaa'.replace(/a/g, 'b')                   // 同上(正则 + g 标志)

// 用函数动态替换
'a1b2c3'.replace(/\d/g, n => Number(n) * 10)  // 'a10b20c30'

分割 / 拼接

'a,b,c'.split(',')                 // ['a', 'b', 'c']
'a,b,c'.split('')                  // ['a', ',', 'b', ...]
'hello'.split('')                  // ['h','e','l','l','o']

['a', 'b', 'c'].join('-')          // 'a-b-c'

重复 / 填充

'-'.repeat(10)                     // '----------'
'5'.padStart(3, '0')               // '005'
'5'.padEnd(3, '.')                 // '5..'

模板字符串高级

函数 tag(tagged template)

function highlight(strings, ...values) {
    return strings.reduce((acc, s, i) => {
        const v = values[i] !== undefined ? `<b>${values[i]}</b>` : '';
        return acc + s + v;
    }, '');
}

const name = 'Alice';
const age = 30;
highlight`Hello, ${name}, you are ${age}.`;
// 'Hello, <b>Alice</b>, you are <b>30</b>.'

适合:HTML 安全转义、SQL 安全构造、i18n 等。

正则配合

// 基本匹配
'hello123'.match(/\d+/)             // ['123', ...]
'hello123world456'.match(/\d+/g)    // ['123', '456']

// 测试
/\d+/.test('hello123')              // true

// 提取捕获组
const m = 'name=Alice'.match(/^(\w+)=(\w+)$/);
m[1];   // 'name'
m[2];   // 'Alice'

// 命名捕获
const { groups } = '2026-05-09'.match(/^(?<y>\d+)-(?<m>\d+)-(?<d>\d+)$/);
groups.y, groups.m, groups.d

字符串遍历

const s = 'hello';

for (const ch of s) {
    console.log(ch);
}

// 转数组
[...s]                              // ['h','e','l','l','o']
Array.from(s)                       // 同上

Unicode 注意

'😀'.length                          // 2 !(emoji 占两个 UTF-16 单元)
[...'😀'].length                     // 1
'😀'.codePointAt(0)                  // 128512

中文字符通常长度对(一字符一单元),但要注意 emoji 和某些组合字符。

转字符串

String(42)                          // '42'
(42).toString()                     // '42'
`${42}`                             // '42'
42 + ''                              // '42'(不推荐,可读性差)

  • 字符串不可变——s[0] = 'X' 不报错但没用
  • '==' + 1 + 2 = '==12'(拼接);'1' + '+' + 2 也是拼接——+ 遇 string 优先拼
  • parseInt('42px') = 42;Number('42px') = NaN——选哪个看场景
  • 大量字符串拼接用 Array.join(性能比 + 好很多)

下一篇:错误处理。