← JavaScript数组方法 没有下一篇了 →

JavaScript字符串

原创 2026-03-13 JavaScript 已有人查阅

JavaScript字符串方法指南:从基础操作到实战应用

什么是字符串?

在JavaScript中,字符串是一系列字符的,可以包含字母、数字、符号以及特殊字符(如换行符\n、制表符\t等)。字符串是编程中最常用的数据类型之一,用于表示文本信息。

// 字符串的几种表示方式
let name = '张三';              // 单引号
let message = "Hello World";    // 双引号
let template = `年龄:${25}`;    // 模板字符串(ES6)
let number = "12345";           // 数字字符串
let special = "换行符:\n新行";   // 包含特殊字符

创建字符串的两种方式:

// 1. 字符串字面量(推荐)
let str1 = 'JavaScript';

// 2. 字符串对象(不推荐,除非特殊需要)
let str2 = new String('JavaScript');

console.log(typeof str1);  // string
console.log(typeof str2);  // object

个人经验:日常开发中始终使用字符串字面量,除非你需要使用字符串对象的一些特殊特性。字面量更简洁,性能也更好。

常用字符串方法详解

1. charAt() - 获取指定位置的字符

返回字符串中指定索引位置的字符。

let str = 'JavaScript编程语言';

// 获取索引2的字符
console.log(str.charAt(2));   // v
console.log(str[2]);          // v(现在写法,更简洁)

// 索引超出范围时
console.log(str.charAt(100));  // ''(空字符串)
console.log(str[100]);         // undefined

// 遍历字符串中的每个字符
for (let i = 0; i < str.length; i++) {
    console.log(`索引${i}: ${str.charAt(i)}`);
}

注意:charAt()和方括号[]的主要区别在于处理越界索引时的返回值不同。方括号语法是ES5引入的更现在的方式。

2. concat() - 拼接字符串

将一个或多个字符串与原字符串拼接,返回新字符串。

let hello = '你好';
let name = '张三';
let punctuation = '!';

// 使用concat拼接
let message1 = hello.concat(' ', name, punctuation);
console.log(message1);  // '你好 张三!'

// 更常见的写法(使用+运算符)
let message2 = hello + ' ' + name + punctuation;
console.log(message2);  // '你好 张三!'

// 模板字符串(ES6,推荐)
let message3 = `${hello} ${name}${punctuation}`;
console.log(message3);  // '你好 张三!'

// 实际应用:构建SQL语句(需要谨慎处理SQL注入)
let tableName = 'users';
let condition = 'age > 18';
let query = 'SELECT * FROM '.concat(tableName, ' WHERE ', condition);
console.log(query);  // 'SELECT * FROM users WHERE age > 18'

个人建议:在日常开发中,我很少使用concat()方法。字符串拼接用+运算符更简洁,而复杂的字符串构建用模板字符串最直观。

3. indexOf() - 查找子串位置

返回指定子串在原字符串中首次出现的索引,找不到返回-1。

let sentence = 'JavaScript是一门编程语言,JavaScript非常强大';

// 基本使用
console.log(sentence.indexOf('编程'));     // 10
console.log(sentence.indexOf('Java'));     // 0
console.log(sentence.indexOf('Python'));   // -1

// 指定开始搜索的位置
console.log(sentence.indexOf('JavaScript', 5));  // 15(从索引5开始找)

// 实际应用:检查字符串是否包含特定内容
function containsKeyword(text, keyword) {
    return text.indexOf(keyword) !== -1;
}

console.log(containsKeyword(sentence, '编程'));  // true
console.log(containsKeyword(sentence, 'Python')); // false

// 统计某个词出现的次数
function countOccurrences(text, word) {
    let count = 0;
    let position = text.indexOf(word);
    
    while (position !== -1) {
        count++;
        position = text.indexOf(word, position + 1);
    }
    
    return count;
}

console.log(countOccurrences(sentence, 'JavaScript'));  // 2

4. lastIndexOf() - 从后查找子串位置

返回指定子串在原字符串中之后一次出现的索引。

let sentence = 'JavaScript是一门编程语言,JavaScript非常强大';

console.log(sentence.lastIndexOf('JavaScript'));  // 15
console.log(sentence.lastIndexOf('编程'));         // 10
console.log(sentence.lastIndexOf('Python'));       // -1

// 指定结束搜索的位置(从开头到指定索引)
console.log(sentence.lastIndexOf('JavaScript', 10));  // 0(只搜索前10个字符)

// 实际应用:获取文件扩展名
function getFileExtension(filename) {
    let lastDotIndex = filename.lastIndexOf('.');
    if (lastDotIndex === -1) return '';  // 没有扩展名
    return filename.slice(lastDotIndex + 1);
}

console.log(getFileExtension('document.pdf'));     // 'pdf'
console.log(getFileExtension('photo.jpg'));        // 'jpg'
console.log(getFileExtension('archive.tar.gz'));   // 'gz'(注意:只取之后一个点后面的)

5. toLowerCase() 和 toUpperCase() - 大小写转换

将字符串中的所有字母转换为小写或大写。

let mixed = 'JavaScript Is AWESOME! 123';

// 转小写
let lower = mixed.toLowerCase();
console.log(lower);  // 'javascript is awesome! 123'

// 转大写
let upper = mixed.toUpperCase();
console.log(upper);  // 'JASCRIPT IS AWESOME! 123'

// 原字符串不变
console.log(mixed);  // 'JavaScript Is AWESOME! 123'

// 实际应用:不区分大小写的比较
function compareIgnoreCase(str1, str2) {
    return str1.toLowerCase() === str2.toLowerCase();
}

console.log(compareIgnoreCase('Hello', 'HELLO'));     // true
console.log(compareIgnoreCase('Java', 'JavaScript')); // false

// 实际应用:首字母大写
function capitalizeFirst(str) {
    if (!str) return '';
    return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
}

console.log(capitalizeFirst('javaSCRIPT'));  // 'Javascript'
console.log(capitalizeFirst('hello world')); // 'Hello world'

6. split() - 分割字符串

根据指定的分隔符将字符串拆分成数组。

let str = '苹果,香蕉,橙子,葡萄,西瓜';

// 基本分割
let fruits = str.split(',');
console.log(fruits);  // ['苹果', '香蕉', '橙子', '葡萄', '西瓜']

// 限制返回数量
let limited = str.split(',', 3);
console.log(limited);  // ['苹果', '香蕉', '橙子']

// 分割每个字符
let chars = 'Hello'.split('');
console.log(chars);  // ['H', 'e', 'l', 'l', 'o']

// 使用正则表达式分割
let text = 'Hello1World2JavaScript';
let parts = text.split(/\d/);  // 按数字分割
console.log(parts);  // ['Hello', 'World', 'JavaScript']

// 实际应用:解析CSV数据
let csvLine = '张三,25,北京,工程师';
let userData = csvLine.split(',');
console.log('姓名:', userData[0]);  // '张三'
console.log('年龄:', userData[1]);  // '25'
console.log('城市:', userData[2]);  // '北京'

// 实际应用:解析URL参数
function parseQueryString(queryString) {
    if (!queryString) return {};
    
    return queryString
        .split('&')
        .map(pair => pair.split('='))
        .reduce((params, [key, value]) => {
            params[key] = decodeURIComponent(value || '');
            return params;
        }, {});
}

let query = 'name=张三&age=25&city=北京';
console.log(parseQueryString(query));
// { name: '张三', age: '25', city: '北京' }

7. slice() - 提取子串

提取字符串的一部分并返回新字符串,支持负数索引。

let str = 'JavaScript编程语言';

// 基本用法:slice(start, end) - 从start到end(不包括end)
console.log(str.slice(0, 4));     // 'Java'
console.log(str.slice(4, 10));    // 'Script'

// 只指定起始位置
console.log(str.slice(4));        // 'Script编程语言'

// 负数索引(从末尾开始计数)
console.log(str.slice(-3));       // '语言'
console.log(str.slice(-6, -3));   // '编程'

// 实际应用:截取邮箱用户名
function getEmailUsername(email) {
    let atIndex = email.indexOf('@');
    if (atIndex === -1) return email;
    return email.slice(0, atIndex);
}

console.log(getEmailUsername('zhangsan@example.com'));  // 'zhangsan'

// 实际应用:截取文件路径中的文件名
function getFileName(filePath) {
    let lastSlash = filePath.lastIndexOf('/');
    if (lastSlash === -1) return filePath;
    return filePath.slice(lastSlash + 1);
}

console.log(getFileName('/users/documents/report.pdf'));  // 'report.pdf'

8. substring() - 另一种提取子串的方法

与slice类似,但不支持负数索引,且会自动调整参数顺序。

let str = 'JavaScript编程语言';

// 基本用法
console.log(str.substring(0, 4));   // 'Java'
console.log(str.substring(4, 10));  // 'Script'

// 自动调整顺序:如果start > end,会交换它们
console.log(str.substring(10, 4));  // 'Script'(等同于substring(4,10))

// 负数被视为0
console.log(str.substring(-5, 4));  // 'Java'(-5被视为0)

// slice和substring的区别
let  = 'Hello World';

// 负数索引
console.log(.slice(-5));        // 'World'
console.log(.substring(-5));    // 'Hello World'(-5被视为0)

// start > end
console.log(.slice(6, 0));      // ''(返回空字符串)
console.log(.substring(6, 0));  // 'Hello'(自动交换为0,6)

个人建议:我倾向于使用slice(),因为它支持负数索引且行为更可预测。只有在需要自动参数交换这个特性时才考虑使用substring()。

9. substr() - 从指定位置提取指定长度的子串

let str = 'JavaScript编程语言';

// substr(start, length) - 从start开始,提取length个字符
console.log(str.substr(0, 4));   // 'Java'
console.log(str.substr(4, 6));   // 'Script'

// 只指定start
console.log(str.substr(4));      // 'Script编程语言'

// 负数start
console.log(str.substr(-3));     // '语言'
console.log(str.substr(-6, 3));  // '编程'

// 实际应用:截取定长字符串
function truncate(text, maxLength) {
    if (text.length <= maxLength) return text;
    return text.substr(0, maxLength) + '...';
}

console.log(truncate('这是一段很长的文本内容', 8));  // '这是一段很...'

注意:substr()是一个遗留方法,不推荐在新代码中使用。建议使用slice()或substring()作为替代。

更多字符串方法

10. trim() - 去除两端空白

let str = '   Hello World   ';
console.log(`"${str}"`);            // "   Hello World   "
console.log(`"${str.trim()}"`);     // "Hello World"

// 只去除左侧空白
console.log(`"${str.trimStart()}"`); // "Hello World   "
console.log(`"${str.trimLeft()}"`);  // "Hello World   "(别名)

// 只去除右侧空白
console.log(`"${str.trimEnd()}"`);   // "   Hello World"
console.log(`"${str.trimRight()}"`); // "   Hello World"(别名)

// 实际应用:处理用户输入
function processUserInput(input) {
    let cleaned = input.trim();
    if (cleaned === '') {
        return '输入不能为空';
    }
    return cleaned;
}

console.log(processUserInput('  张三  '));  // '张三'
console.log(processUserInput('   '));       // '输入不能为空'

11. replace() - 替换子串

let str = '我喜欢JavaScript,JavaScript很有趣';

// 只替换第一个匹配项
let replaced1 = str.replace('JavaScript', 'Python');
console.log(replaced1);  // '我喜欢Python,JavaScript很有趣'

// 使用正则表达式全局替换
let replaced2 = str.replace(/JavaScript/g, 'Python');
console.log(replaced2);  // '我喜欢Python,Python很有趣'

// 使用函数进行动态替换
let replaced3 = str.replace(/JavaScript/g, (match, offset) => {
    return offset === 0  '前端开发' : '编程';
});
console.log(replaced3);  // '我喜欢前端开发,编程很有趣'

// 实际应用:敏感词过滤
function censor(text, badWords) {
    let result = text;
    badWords.forEach(word => {
        let regex = new RegExp(word, 'gi');
        result = result.replace(regex, '*'.repeat(word.length));
    });
    return result;
}

let comment = '这个网站太垃圾了,管理员是笨蛋';
let filtered = censor(comment, ['垃圾', '笨蛋']);
console.log(filtered);  // '这个网站太**了,管理员是**'

12. includes() - 检查是否包含子串(ES6)

let str = 'JavaScript编程语言';

console.log(str.includes('Java'));      // true
console.log(str.includes('Python'));    // false
console.log(str.includes('Script', 4)); // true(从索引4开始检查)

// 实际应用:搜索过滤
let products = [
    'iPhone手机',
    '华为手机',
    '小米平板',
    '联想电脑'
];

function searchProducts(keyword) {
    return products.filter(product => 
        product.includes(keyword)
    );
}

console.log(searchProducts('手机'));  // ['iPhone手机', '华为手机']
console.log(searchProducts('电脑'));  // ['联想电脑']

13. startsWith() 和 endsWith() - 检查开头和结尾(ES6)

let url = 'https://example.com/index.html';

console.log(url.startsWith('https'));     // true
console.log(url.startsWith('http'));      // false
console.log(url.startsWith('example', 8)); // true(从索引8开始检查)

console.log(url.endsWith('.html'));       // true
console.log(url.endsWith('.php'));        // false
console.log(url.endsWith('example', 16));  // true(只考虑前16个字符)

// 实际应用:URL协议检查
function isSecureUrl(url) {
    return url.startsWith('https://');
}

console.log(isSecureUrl('https://google.com'));  // true
console.log(isSecureUrl('http://example.com'));  // false

// 实际应用:文件类型过滤
function isImageFile(filename) {
    return filename.endsWith('.jpg') || 
           filename.endsWith('.png') || 
           filename.endsWith('.gif');
}

console.log(isImageFile('photo.jpg'));   // true
console.log(isImageFile('document.pdf')); // false

14. repeat() - 重复字符串(ES6)

let str = '哈';

console.log(str.repeat(3));    // '哈哈哈'
console.log('='.repeat(10));   // '=========='
console.log('*'.repeat(5));    // '*****'

// 实际应用:创建分隔线
function createDivider(char = '-', length = 30) {
    return char.repeat(length);
}

console.log(createDivider());        // '------------------------------'
console.log(createDivider('=', 20)); // '===================='

// 实际应用:文本对齐
function padLeft(text, width, char = ' ') {
    if (text.length >= width) return text;
    return char.repeat(width - text.length) + text;
}

console.log(padLeft('123', 5));       // '  123'
console.log(padLeft('abc', 6, '*'));  // '***abc'

15. padStart() 和 padEnd() - 填充字符串(ES2017)

let str = '5';

// padStart(targetLength, padString) - 在开头填充
console.log(str.padStart(3, '0'));      // '005'
console.log(str.padStart(5, 'ab'));     // 'abab5'
console.log(str.padStart(2));           // ' 5'(默认用空格)

// padEnd() - 在末尾填充
console.log(str.padEnd(3, '0'));        // '500'
console.log(str.padEnd(5, 'ab'));       // '5abab'

// 实际应用:格式化序号
function formatNumber(num, digits = 3) {
    return num.toString().padStart(digits, '0');
}

for (let i = 1; i <= 10; i++) {
    console.log(`编号:${formatNumber(i)}`);  // 001, 002, 003...
}

// 实际应用:表格对齐
function printTable(rows) {
    rows.forEach(([key, value]) => {
        console.log(
            key.padEnd(10) + ' | ' + 
            value.toString().padStart(8)
        );
    });
}

printTable([
    ['名称', '价格'],
    ['苹果', 5],
    ['香蕉', 3],
    ['西瓜', 8]
]);

16. match() - 正则匹配

let str = '今天是2026年3月13日,气温15°C';

// 匹配数字
let numbers = str.match(/\d+/g);
console.log(numbers);  // ['2026', '3', '13', '15']

// 匹配日期
let dateMatch = str.match(/(\d+)年(\d+)月(\d+)日/);
if (dateMatch) {
    console.log('完整匹配:', dateMatch[0]);  // '2026年3月13日'
    console.log('年:', dateMatch[1]);        // '2026'
    console.log('月:', dateMatch[2]);        // '3'
    console.log('日:', dateMatch[3]);        // '13'
}

// 实际应用:提取邮箱中的用户名和域名
function parseEmail(email) {
    let match = email.match(/^([^@]+)@(.+)$/);
    if (!match) return null;
    return {
        username: match[1],
        domain: match[2]
    };
}

console.log(parseEmail('zhangsan@example.com'));
// { username: 'zhangsan', domain: 'example.com' }

17. search() - 搜索正则匹配的位置

let str = 'Hello, 123 World! 456';

console.log(str.search(/\d+/));      // 7(第一个数字的位置)
console.log(str.search(/[A-Z]/));     // 0(第一个大写字母)
console.log(str.search(/[a-z]/));     // 1(第一个小写字母)
console.log(str.search(/[x-z]/));     // -1(找不到)

// 实际应用:检查字符串是否包含特定模式
function hasPattern(text, pattern) {
    return text.search(pattern) !== -1;
}

console.log(hasPattern('user@example.com', /@/));           // true
console.log(hasPattern('电话号码:13800138000', /\d{11}/)); // true

18. localeCompare() - 本地化比较

let names = ['张三', '李四', '王五', '赵六', '陈七'];

// 默认排序(不符合中文习惯)
console.log([...names].sort());

// 使用localeCompare进行中文排序
let sortedCN = [...names].sort((a, b) => a.localeCompare(b, 'zh-CN'));
console.log(sortedCN);  // 按照中文拼音排序

// 忽略大小写比较
let str1 = 'Apple';
let str2 = 'apple';
console.log(str1.localeCompare(str2, undefined, { sensitivity: 'base' })); // 0(视为相等)

// 实际应用:多语言排序
function sortMultilingual(array, locale = 'zh-CN') {
    return [...array].sort((a, b) => a.localeCompare(b, locale));
}

let mixed = ['éclair', 'apple', 'zebra', 'café'];
console.log(sortMultilingual(mixed, 'fr'));  // 法语排序

课程知识要点

  1. 字符串定义:字符的,可用单引号、双引号、反引号创建

  2. 访问字符:charAt()、方括号[]、at()(ES2022)

  3. 查找方法:indexOf()、lastIndexOf()、includes()、startsWith()、endsWith()

  4. 提取方法:slice()、substring()、substr()(遗留)

  5. 转换方法:toLowerCase()、toUpperCase()、split()、join()

  6. 替换方法:replace()、replaceAll()(ES2021)

  7. 填充方法:padStart()、padEnd()、repeat()

  8. 修剪方法:trim()、trimStart()、trimEnd()

  9. 正则方法:match()、search()、matchAll()(ES2020)

  10. 比较方法:localeCompare()支持本地化排序

开发实践建议

基于多年JavaScript开发经验,我对字符串方法的使用建议如下:

// 1. 优先使用现在方法
let text = '  Hello World  ';

// 现在(简洁)
if (text.includes('Hello')) { ... }
if (text.startsWith('Hello')) { ... }
let cleaned = text.trim();

// 传统(繁琐)
if (text.indexOf('Hello') !== -1) { ... }
if (text.indexOf('Hello') === 0) { ... }
let cleaned = text.replace(/^\s+|\s+$/g, '');

// 2. 模板字符串优于拼接
let name = '张三';
let age = 25;

// 推荐
let info = `姓名:${name},年龄:${age}`;

// 不推荐
let info2 = '姓名:' + name + ',年龄:' + age;

// 3. 链式调用
let result = '  JavaScript is awesome  '
    .trim()
    .toLowerCase()
    .replace('awesome', 'great')
    .split(' ')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');

console.log(result);  // 'JavaScript Is Great'

// 4. 处理用户输入时始终trim
function validateInput(input) {
    let value = input.trim();
    if (!value) {
        return '输入不能为空';
    }
    return value;
}

// 5. 正则表达式与字符串方法结合使用
function extractEmails(text) {
    const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
    return text.match(emailRegex) || [];
}

let sample = '联系我们:support@example.com 或 sales@company.com.cn';
console.log(extractEmails(sample));
// ['support@example.com', 'sales@company.com.cn']

字符串处理是日常开发中最常见的任务之一,掌握这些方法能够让你更高效地处理文本数据。随着ECMAScript的演进,字符串方法越来越丰富,代码也变得越来越简洁易读。

← JavaScript数组方法 没有下一篇了 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号