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 = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
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")); // 33. 搜索和过滤工具
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 字符串的核心要点:
- 创建方式:字符串字面量、String 构造函数
- 基本属性:length 属性
- 查找方法:indexOf、lastIndexOf、includes、startsWith、endsWith
- 截取方法:slice、substring、substr
- 转换方法:toUpperCase、toLowerCase、trim、padStart、padEnd
- 分割连接:split、join
- 替换方法:replace、replaceAll
- 模板字符串:支持多行和表达式插值
- Unicode 处理:正确处理多字节字符
- 性能优化:合理选择字符串连接方式
- 最佳实践:输入验证、格式化、安全处理
掌握字符串处理是 JavaScript 开发的基础技能。在下一章节中,我们将学习 JavaScript 的运算符。