Skip to content

JavaScript 字符串

字符串是 JavaScript 中的基本数据类型之一,用于表示文本数据。在 Web 开发中,字符串处理是非常常见的操作,包括用户输入处理、数据格式化、模板生成等。掌握字符串的操作方法对于编写高效的 JavaScript 代码至关重要。在本章节中,我们将深入学习 JavaScript 中字符串的各种操作和处理方法。

什么是字符串

字符串是由零个或多个字符组成的序列,用单引号(')、双引号(")或反引号(`)包围。字符串是不可变的,一旦创建就不能修改。

javascript
// 字符串字面量
const singleQuote = '单引号字符串';
const doubleQuote = "双引号字符串";
const backtick = `反引号字符串`;

// 空字符串
const emptyString = "";
const anotherEmpty = '';

// 包含引号的字符串
const withQuotes = '他说:"你好!"';
const withApostrophe = "这是 John's 书";

字符串的创建方式

1. 字符串字面量

javascript
const str1 = "Hello World";
const str2 = 'JavaScript';
const str3 = `模板字符串`;

2. String 构造函数

javascript
const str1 = new String("Hello");
const str2 = String("World");

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

3. 字符串连接

javascript
const firstName = "张";
const lastName = "三";
const fullName = firstName + lastName; // "张三"
const greeting = "你好," + fullName + "!"; // "你好,张三!"

// 使用 += 操作符
let message = "Hello";
message += " World"; // "Hello World"

字符串的属性和方法

基本属性

javascript
const str = "JavaScript";

// length 属性 - 获取字符串长度
console.log(str.length); // 10

// 访问单个字符
console.log(str[0]);     // "J"
console.log(str.charAt(0)); // "J"
console.log(str.charCodeAt(0)); // 74 (Unicode 值)

查找方法

javascript
const text = "JavaScript 是一种强大的编程语言,JavaScript 很流行";

// indexOf() - 查找子字符串第一次出现的位置
console.log(text.indexOf("JavaScript")); // 0
console.log(text.indexOf("JavaScript", 5)); // 18 (从位置5开始查找)

// lastIndexOf() - 查找子字符串最后一次出现的位置
console.log(text.lastIndexOf("JavaScript")); // 18

// includes() - 检查是否包含子字符串
console.log(text.includes("编程")); // true
console.log(text.includes("Python")); // false

// startsWith() - 检查是否以指定字符串开头
console.log(text.startsWith("JavaScript")); // true
console.log(text.startsWith("编程")); // false

// endsWith() - 检查是否以指定字符串结尾
console.log(text.endsWith("流行")); // true
console.log(text.endsWith("JavaScript")); // false

// search() - 使用正则表达式查找
console.log(text.search(/javascript/i)); // 0 (忽略大小写)

截取方法

javascript
const str = "JavaScript 编程语言";

// slice() - 提取字符串的一部分
console.log(str.slice(0, 10));    // "JavaScript"
console.log(str.slice(11));       // "编程语言"
console.log(str.slice(-4));       // "语言" (从倒数第4个字符开始)
console.log(str.slice(-4, -2));   // "编程"

// substring() - 提取字符串的一部分
console.log(str.substring(0, 10)); // "JavaScript"
console.log(str.substring(11));    // "编程语言"

// substr() - 已废弃,但仍可使用
console.log(str.substr(0, 10));   // "JavaScript"
console.log(str.substr(11, 4));   // "编程"

转换方法

javascript
const str = "JavaScript Programming";

// toUpperCase() - 转换为大写
console.log(str.toUpperCase()); // "JAVASCRIPT PROGRAMMING"

// toLowerCase() - 转换为小写
console.log(str.toLowerCase()); // "javascript programming"

// trim() - 去除首尾空白字符
const spacedStr = "  Hello World  ";
console.log(spacedStr.trim());     // "Hello World"
console.log(spacedStr.trimStart()); // "Hello World  "
console.log(spacedStr.trimEnd());   // "  Hello World"

// padStart() 和 padEnd() - 填充字符串
const number = "42";
console.log(number.padStart(5, "0")); // "00042"
console.log(number.padEnd(5, "0"));   // "42000"

// repeat() - 重复字符串
console.log("Hello".repeat(3)); // "HelloHelloHello"

分割和连接方法

javascript
const str = "apple,banana,orange";

// split() - 分割字符串为数组
console.log(str.split(","));        // ["apple", "banana", "orange"]
console.log(str.split(",", 2));     // ["apple", "banana"]
console.log("Hello World".split(" ")); // ["Hello", "World"]
console.log("Hello".split(""));     // ["H", "e", "l", "l", "o"]

// join() - 数组连接为字符串(数组方法)
const fruits = ["apple", "banana", "orange"];
console.log(fruits.join(", "));     // "apple, banana, orange"
console.log(fruits.join(" | "));    // "apple | banana | orange"

替换方法

javascript
const text = "JavaScript 是一种强大的编程语言,JavaScript 很流行";

// replace() - 替换第一个匹配项
console.log(text.replace("JavaScript", "Python")); 
// "Python 是一种强大的编程语言,JavaScript 很流行"

// replaceAll() - 替换所有匹配项(ES2021)
console.log(text.replaceAll("JavaScript", "Python"));
// "Python 是一种强大的编程语言,Python 很流行"

// 使用正则表达式替换
console.log(text.replace(/javascript/gi, "Python"));
// "Python 是一种强大的编程语言,Python 很流行"

// 使用函数作为替换值
console.log(text.replace("JavaScript", (match) => match.toUpperCase()));
// "JAVASCRIPT 是一种强大的编程语言,JavaScript 很流行"

模板字符串(Template Literals)- ES6

模板字符串使用反引号(`)包围,支持多行字符串和表达式插值。

javascript
// 基本用法
const name = "张三";
const age = 25;
const greeting = `你好,我是${name},今年${age}岁`;
console.log(greeting); // "你好,我是张三,今年25岁"

// 多行字符串
const multiline = `
这是第一行
这是第二行
这是第三行
`;
console.log(multiline);

// 表达式插值
const a = 5;
const b = 3;
const result = `${a} + ${b} = ${a + b}`;
console.log(result); // "5 + 3 = 8"

// 嵌套模板字符串
const price = 100;
const tax = 0.1;
const total = `总价:${price * (1 + tax)}元(含${tax * 100}%税费)`;
console.log(total); // "总价:110元(含10%税费)"

// 标签模板(Tagged Templates)
function highlight(strings, ...values) {
    let result = "";
    strings.forEach((string, i) => {
        result += string;
        if (values[i]) {
            result += `<mark>${values[i]}</mark>`;
        }
    });
    return result;
}

const person = "张三";
const skill = "JavaScript";
const description = highlight`我是${person},我擅长${skill}编程`;
console.log(description); // "我是<mark>张三</mark>,我擅长<mark>JavaScript</mark>编程"

字符串的 Unicode 处理

javascript
// Unicode 字符
const unicodeStr = "Hello 世界 🌍";

// 正确处理 Unicode 字符长度
console.log(unicodeStr.length); // 9

// 使用 Array.from() 获取正确字符数
console.log(Array.from(unicodeStr).length); // 8

// codePointAt() - 获取 Unicode 码点
console.log("🌍".codePointAt(0)); // 127757

// fromCodePoint() - 从码点创建字符
console.log(String.fromCodePoint(127757)); // "🌍"

// normalize() - Unicode 标准化
const str1 = "café";  // 包含组合字符
const str2 = "café";  // 包含预组合字符
console.log(str1 === str2); // false
console.log(str1.normalize() === str2.normalize()); // true

字符串的比较

javascript
const str1 = "apple";
const str2 = "Apple";
const str3 = "banana";

// 直接比较
console.log(str1 === str2); // false (区分大小写)
console.log(str1 < str3);   // true (按字典顺序)

// 忽略大小写比较
console.log(str1.toLowerCase() === str2.toLowerCase()); // true

// localeCompare() - 本地化比较
console.log(str1.localeCompare(str2)); // 1 (str1 > str2)
console.log(str1.localeCompare(str2, undefined, { sensitivity: 'base' })); // 0 (忽略大小写)

// 数字字符串比较
const numStr1 = "10";
const numStr2 = "2";
console.log(numStr1 < numStr2); // true (按字符串比较)
console.log(Number(numStr1) < Number(numStr2)); // false (按数字比较)

字符串的性能优化

1. 字符串连接优化

javascript
// 对于少量字符串连接,使用 + 操作符
const result1 = "Hello" + " " + "World";

// 对于大量字符串连接,使用数组 join
function concatenateStrings(strings) {
    return strings.join("");
}

// 对于循环中的字符串连接,使用数组
function buildString(items) {
    const parts = [];
    for (let item of items) {
        parts.push(`<li>${item}</li>`);
    }
    return `<ul>${parts.join("")}</ul>`;
}

2. 字符串缓存

javascript
// 避免重复创建相同的字符串
const templates = {
    header: "<header>网站头部</header>",
    footer: "<footer>网站底部</footer>"
};

function renderPage(content) {
    return templates.header + content + templates.footer;
}

字符串处理的最佳实践

1. 输入验证

javascript
function validateEmail(email) {
    if (typeof email !== "string") {
        return false;
    }
    
    // 去除首尾空白
    email = email.trim();
    
    // 基本格式检查
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
}

function validateUsername(username) {
    if (typeof username !== "string") {
        return false;
    }
    
    // 去除首尾空白
    username = username.trim();
    
    // 长度检查
    if (username.length < 3 || username.length > 20) {
        return false;
    }
    
    // 字符检查
    const usernameRegex = /^[a-zA-Z0-9_]+$/;
    return usernameRegex.test(username);
}

2. 字符串格式化

javascript
// 数字格式化
function formatCurrency(amount) {
    return `¥${amount.toFixed(2)}`;
}

function formatPercentage(value) {
    return `${(value * 100).toFixed(1)}%`;
}

// 日期格式化
function formatDate(date) {
    if (!(date instanceof Date)) {
        date = new Date(date);
    }
    
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    
    return `${year}-${month}-${day}`;
}

// 电话号码格式化
function formatPhoneNumber(phone) {
    // 移除所有非数字字符
    const digits = phone.replace(/\D/g, "");
    
    // 格式化为 XXX-XXXX-XXXX
    if (digits.length === 11) {
        return `${digits.slice(0, 3)}-${digits.slice(3, 7)}-${digits.slice(7)}`;
    }
    
    return phone;
}

3. 安全处理

javascript
// HTML 转义
function escapeHtml(text) {
    const map = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#039;'
    };
    
    return text.replace(/[&<>"']/g, (m) => map[m]);
}

// URL 编码
function buildQueryString(params) {
    const pairs = [];
    for (let key in params) {
        if (params.hasOwnProperty(key)) {
            pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`);
        }
    }
    return pairs.join("&");
}

实际应用示例

1. 模板引擎简化版

javascript
class SimpleTemplate {
    constructor(template) {
        this.template = template;
    }
    
    render(data) {
        let result = this.template;
        
        // 替换 {{variable}} 形式的变量
        for (let key in data) {
            if (data.hasOwnProperty(key)) {
                const pattern = new RegExp(`{{\\s*${key}\\s*}}`, 'g');
                result = result.replace(pattern, data[key]);
            }
        }
        
        return result;
    }
}

// 使用示例
const template = new SimpleTemplate(`
<h1>{{title}}</h1>
<p>作者:{{author}}</p>
<p>发布时间:{{date}}</p>
<div>{{content}}</div>
`);

const data = {
    title: "JavaScript 字符串处理",
    author: "张三",
    date: "2024-01-01",
    content: "这是文章内容..."
};

const html = template.render(data);
console.log(html);

2. 字符串工具库

javascript
const StringUtils = {
    // 驼峰命名转换
    toCamelCase(str) {
        return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
    },
    
    // 帕斯卡命名转换
    toPascalCase(str) {
        return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '')
                 .replace(/^./, (match) => match.toUpperCase());
    },
    
    // 蛇形命名转换
    toSnakeCase(str) {
        return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
                 .replace(/^-+/, '');
    },
    
    // 随机字符串生成
    randomString(length = 10) {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        let result = '';
        for (let i = 0; i < length; i++) {
            result += chars.charAt(Math.floor(Math.random() * chars.length));
        }
        return result;
    },
    
    // 字符串截断
    truncate(str, maxLength, suffix = '...') {
        if (str.length <= maxLength) {
            return str;
        }
        return str.substring(0, maxLength - suffix.length) + suffix;
    },
    
    // 单词首字母大写
    capitalize(str) {
        return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
    },
    
    // 统计单词数
    wordCount(str) {
        return str.trim().split(/\s+/).filter(word => word.length > 0).length;
    }
};

// 使用示例
console.log(StringUtils.toCamelCase("hello-world")); // "helloWorld"
console.log(StringUtils.toPascalCase("hello-world")); // "HelloWorld"
console.log(StringUtils.toSnakeCase("helloWorld")); // "hello_world"
console.log(StringUtils.randomString(8)); // 随机8位字符串
console.log(StringUtils.truncate("这是一个很长的字符串", 10)); // "这是一个很..."
console.log(StringUtils.capitalize("hello")); // "Hello"
console.log(StringUtils.wordCount("Hello world JavaScript")); // 3

3. 搜索和过滤工具

javascript
class StringSearcher {
    constructor(options = {}) {
        this.caseSensitive = options.caseSensitive || false;
        this.wholeWord = options.wholeWord || false;
    }
    
    // 简单搜索
    search(text, query) {
        if (!this.caseSensitive) {
            text = text.toLowerCase();
            query = query.toLowerCase();
        }
        
        return text.includes(query);
    }
    
    // 高亮匹配文本
    highlight(text, query, highlightTag = "mark") {
        if (!query) return text;
        
        let searchText = text;
        let searchQuery = query;
        
        if (!this.caseSensitive) {
            searchText = text.toLowerCase();
            searchQuery = query.toLowerCase();
        }
        
        const index = searchText.indexOf(searchQuery);
        if (index === -1) return text;
        
        const before = text.substring(0, index);
        const match = text.substring(index, index + query.length);
        const after = text.substring(index + query.length);
        
        return `${before}<${highlightTag}>${match}</${highlightTag}>${after}`;
    }
    
    // 模糊搜索
    fuzzySearch(text, query) {
        let textIndex = 0;
        let queryIndex = 0;
        
        while (textIndex < text.length && queryIndex < query.length) {
            let textChar = text[textIndex];
            let queryChar = query[queryIndex];
            
            if (!this.caseSensitive) {
                textChar = textChar.toLowerCase();
                queryChar = queryChar.toLowerCase();
            }
            
            if (textChar === queryChar) {
                queryIndex++;
            }
            textIndex++;
        }
        
        return queryIndex === query.length;
    }
}

// 使用示例
const searcher = new StringSearcher({ caseSensitive: false });

console.log(searcher.search("Hello World", "world")); // true
console.log(searcher.highlight("Hello World", "world")); // "Hello <mark>World</mark>"
console.log(searcher.fuzzySearch("JavaScript", "JVS")); // true

总结

JavaScript 字符串的核心要点:

  1. 创建方式:字符串字面量、String 构造函数
  2. 基本属性:length 属性
  3. 查找方法:indexOf、lastIndexOf、includes、startsWith、endsWith
  4. 截取方法:slice、substring、substr
  5. 转换方法:toUpperCase、toLowerCase、trim、padStart、padEnd
  6. 分割连接:split、join
  7. 替换方法:replace、replaceAll
  8. 模板字符串:支持多行和表达式插值
  9. Unicode 处理:正确处理多字节字符
  10. 性能优化:合理选择字符串连接方式
  11. 最佳实践:输入验证、格式化、安全处理

掌握字符串处理是 JavaScript 开发的基础技能。在下一章节中,我们将学习 JavaScript 的运算符。

本站内容仅供学习和研究使用。