字符串新方法(String Methods)
概述
ES6 为字符串引入了多个新方法,使字符串操作更加方便和直观。
查找方法
String.prototype.includes()
判断字符串是否包含指定的子字符串:
const str = 'Hello, World!';
console.log(str.includes('World')); // true
console.log(str.includes('world')); // false(区分大小写)
console.log(str.includes('Hello', 6)); // false(从索引 6 开始查找)
// 实际应用
const email = 'user@example.com';
if (email.includes('@')) {
console.log('有效的邮箱格式');
}
// 检查文件扩展名
const filename = 'document.pdf';
if (filename.includes('.pdf')) {
console.log('这是一个 PDF 文件');
}
String.prototype.startsWith()
判断字符串是否以指定的子字符串开头:
const str = 'Hello, World!';
console.log(str.startsWith('Hello')); // true
console.log(str.startsWith('World')); // false
console.log(str.startsWith('World', 7)); // true(从索引 7 开始)
// 实际应用
const url = 'https://api.example.com/users';
if (url.startsWith('https://')) {
console.log('安全连接');
}
// 检查协议
const path = '/api/users';
if (path.startsWith('/api')) {
console.log('API 路径');
}
String.prototype.endsWith()
判断字符串是否以指定的子字符串结尾:
const str = 'Hello, World!';
console.log(str.endsWith('World!')); // true
console.log(str.endsWith('Hello')); // false
console.log(str.endsWith('Hello', 5)); // true(检查前 5 个字符)
// 实际应用
const filename = 'document.pdf';
if (filename.endsWith('.pdf')) {
console.log('PDF 文件');
}
// 检查文件类型
function isImageFile(filename) {
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp'];
return imageExtensions.some(ext => filename.endsWith(ext));
}
console.log(isImageFile('photo.jpg')); // true
console.log(isImageFile('document.pdf')); // false
重复方法
String.prototype.repeat()
返回指定次数重复的字符串:
const str = 'abc';
console.log(str.repeat(0)); // ''
console.log(str.repeat(1)); // 'abc'
console.log(str.repeat(2)); // 'abcabc'
console.log(str.repeat(3)); // 'abcabcabc'
// 实际应用
// 生成分隔线
const separator = '-'.repeat(50);
console.log(separator);
// --------------------------------------------------
// 生成缩进
function indent(level, char = ' ') {
return char.repeat(level * 2);
}
console.log(indent(1)); // ' '
console.log(indent(2)); // ' '
// 生成占位符
function maskEmail(email) {
const [local, domain] = email.split('@');
const maskedLocal = local[0] + '*'.repeat(local.length - 1);
return `${maskedLocal}@${domain}`;
}
console.log(maskEmail('john@example.com')); // 'j***@example.com'
填充方法
String.prototype.padStart()
在字符串开头填充指定字符,直到达到指定长度:
const str = '5';
console.log(str.padStart(3, '0')); // '005'
console.log(str.padStart(5, '0')); // '00005'
console.log(str.padStart(3)); // ' 5'(默认填充空格)
// 实际应用
// 格式化时间
function formatTime(hours, minutes, seconds) {
return [
hours.toString().padStart(2, '0'),
minutes.toString().padStart(2, '0'),
seconds.toString().padStart(2, '0')
].join(':');
}
console.log(formatTime(9, 5, 3)); // '09:05:03'
// 格式化订单号
function formatOrderNumber(num) {
return `ORD-${num.toString().padStart(8, '0')}`;
}
console.log(formatOrderNumber(1234)); // 'ORD-00001234'
// 格式化金额
function formatCurrency(amount) {
return amount.toFixed(2).padStart(10, ' ');
}
console.log(formatCurrency(123.4)); // ' 123.40'
String.prototype.padEnd()
在字符串结尾填充指定字符,直到达到指定长度:
const str = 'Hello';
console.log(str.padEnd(10, '.')); // 'Hello.....'
console.log(str.padEnd(10)); // 'Hello '
console.log(str.padEnd(3)); // 'Hello'(已经够长)
// 实际应用
// 格式化表格
function formatTable(rows, columnWidth = 20) {
return rows.map(row =>
row.map(cell =>
cell.toString().padEnd(columnWidth, ' ')
).join('')
).join('\n');
}
const data = [
['Name', 'Age', 'City'],
['John', 25, 'New York'],
['Jane', 30, 'Los Angeles']
];
console.log(formatTable(data));
// Name Age City
// John 25 New York
// Jane 30 Los Angeles
// 对齐输出
function alignText(text, width, align = 'left') {
switch (align) {
case 'left':
return text.padEnd(width);
case 'right':
return text.padStart(width);
case 'center':
const padding = width - text.length;
const leftPad = Math.floor(padding / 2);
const rightPad = padding - leftPad;
return ' '.repeat(leftPad) + text + ' '.repeat(rightPad);
}
}
console.log(alignText('Hello', 20, 'center'));
// ' Hello '
去除空白方法
String.prototype.trim()
去除字符串两端的空白字符:
const str = ' Hello, World! ';
console.log(str.trim()); // 'Hello, World!'
console.log(str.trimStart()); // 'Hello, World! '
console.log(str.trimEnd()); // ' Hello, World!'
// 实际应用
// 清理用户输入
function cleanInput(input) {
return input.trim().toLowerCase();
}
console.log(cleanInput(' John Doe ')); // 'john doe'
// 处理表单数据
function processFormData(data) {
return Object.fromEntries(
Object.entries(data).map(([key, value]) => [
key,
typeof value === 'string' ? value.trim() : value
])
);
}
const formData = { name: ' John ', email: ' john@example.com ' };
console.log(processFormData(formData));
// { name: 'John', email: 'john@example.com' }
模板字符串相关
String.raw()
返回原始字符串(不处理转义字符):
const path = `C:\new\test`;
console.log(path); // C:
// ew est(\n 和 \t 被转义了)
const rawPath = String.raw`C:\new\test`;
console.log(rawPath); // C:\new\test
// 生成正则表达式
const regex = String.raw`\d+\.\d+`;
console.log(new RegExp(regex)); // /\d+\.\d+/
// 在标签模板中使用
function tag(strings, ...values) {
console.log(strings.raw[0]); // "Line 1\nLine 2"
}
tag`Line 1\nLine 2`;
实际应用示例
1. 文本处理工具
const TextUtils = {
// 首字母大写
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
},
// 驼峰命名转下划线
camelToSnake(str) {
return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
},
// 下划线转驼峰命名
snakeToCamel(str) {
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
},
// 截断字符串
truncate(str, length, suffix = '...') {
if (str.length <= length) return str;
return str.slice(0, length - suffix.length) + suffix;
},
// 统计单词数
wordCount(str) {
return str.trim().split(/\s+/).filter(word => word.length > 0).length;
}
};
console.log(TextUtils.capitalize('hello')); // 'Hello'
console.log(TextUtils.camelToSnake('userName')); // 'user_name'
console.log(TextUtils.snakeToCamel('user_name')); // 'userName'
console.log(TextUtils.truncate('Hello, World!', 8)); // 'Hello...'
console.log(TextUtils.wordCount('Hello World foo bar')); // 4
2. 数据格式化
// 格式化数字
function formatNumber(num, options = {}) {
const {
decimals = 0,
thousandsSeparator = ',',
decimalSeparator = '.'
} = options;
const parts = num.toFixed(decimals).split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
return parts.join(decimalSeparator);
}
console.log(formatNumber(1234567.891)); // '1,234,568'
console.log(formatNumber(1234567.891, { decimals: 2 })); // '1,234,567.89'
// 格式化文件大小
function formatFileSize(bytes) {
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
let unitIndex = 0;
let size = bytes;
while (size >= 1024 && unitIndex < units.length - 1) {
size /= 1024;
unitIndex++;
}
return `${size.toFixed(2)} ${units[unitIndex]}`;
}
console.log(formatFileSize(1024)); // '1.00 KB'
console.log(formatFileSize(1234567)); // '1.18 MB'
3. 模板引擎
function renderTemplate(template, data) {
return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
return data.hasOwnProperty(key) ? data[key] : match;
});
}
const template = 'Hello, {{name}}! You have {{count}} new messages.';
const data = { name: 'John', count: 5 };
console.log(renderTemplate(template, data));
// "Hello, John! You have 5 new messages."
// 支持嵌套属性
function renderAdvancedTemplate(template, data) {
return template.replace(/\{\{([^}]+)\}\}/g, (match, path) => {
const keys = path.split('.');
let value = data;
for (const key of keys) {
if (value && typeof value === 'object' && key in value) {
value = value[key];
} else {
return match;
}
}
return value;
});
}
const advancedTemplate = 'User: {{user.name}}, Email: {{user.email}}';
const advancedData = { user: { name: 'John', email: 'john@example.com' } };
console.log(renderAdvancedTemplate(advancedTemplate, advancedData));
// "User: John, Email: john@example.com"
4. 字符串验证
const Validators = {
// 检查是否为空或只包含空白
isEmpty(str) {
return !str || str.trim().length === 0;
},
// 检查邮箱格式
isEmail(str) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);
},
// 检查是否只包含字母
isAlpha(str) {
return /^[a-zA-Z]+$/.test(str);
},
// 检查是否只包含数字
isNumeric(str) {
return /^\d+$/.test(str);
},
// 检查是否是有效 URL
isURL(str) {
try {
new URL(str);
return true;
} catch {
return false;
}
}
};
console.log(Validators.isEmpty(' ')); // true
console.log(Validators.isEmail('john@example.com')); // true
console.log(Validators.isAlpha('Hello')); // true
console.log(Validators.isNumeric('12345')); // true
console.log(Validators.isURL('https://example.com')); // true
最佳实践
- 使用
includes()代替indexOf():更语义化 - 使用
startsWith()和endsWith():检查字符串开头和结尾 - 使用
padStart()和padEnd():格式化输出 - 使用
trim():清理用户输入 - 使用
repeat():生成重复字符串
// 好的做法
if (email.includes('@')) {
// 处理邮箱
}
if (filename.endsWith('.pdf')) {
// 处理 PDF 文件
}
const formatted = number.toString().padStart(8, '0');
// 避免
if (email.indexOf('@') !== -1) {
// 处理邮箱
}
if (filename.slice(-4) === '.pdf') {
// 处理 PDF 文件
}
参考
目录