从基础到实战,掌握
some()、test()、match()、includes()四个核心方法
前言
在日常的 JavaScript 开发中,字符串和数组的操作无处不在。无论是数据验证、文本解析,还是代码扫描工具的开发,掌握这些核心方法都能让代码更简洁、更高效。
本文将以实战为导向,深入讲解四个重要方法:
Array.some()- 数组条件检测RegExp.test()- 正则匹配验证String.match()- 字符串匹配提取String.includes()- 子串包含检查
通过理论+练习的方式,帮助你真正掌握这些API。
一、Array.some() - 数组条件检测
1.1 基本概念
some() 方法用于检查数组中是否至少有一个元素满足指定条件。
语法:
javascript
array.some(callback(element, index, array))
参数:
callback:测试函数,返回布尔值element:当前元素index(可选):当前索引array(可选):调用some()的数组
返回值:
true:至少有一个元素满足条件false:所有元素都不满足条件
1.2 基础示例
javascript
// 示例1:检查数组是否包含偶数
const numbers = [1, 3, 5, 7, 8, 11]
const hasEven = numbers.some(num => num % 2 === 0)
console.log(hasEven) // true(因为有 8)
// 示例2:检查用户是否有管理员权限
const users = [
{ name: '张三', role: 'user' },
{ name: '李四', role: 'admin' },
{ name: '王五', role: 'user' }
]
const hasAdmin = users.some(user => user.role === 'admin')
console.log(hasAdmin) // true
// 示例3:检查数组是否为空
const emptyArr = []
const hasElements = emptyArr.some(() => true)
console.log(hasElements) // false(空数组永远返回 false)
1.3 实战场景:代码扫描工具中的使用
在之前写的硬编码扫描脚本中,我们用 some() 来检测一行代码是否匹配多个国际化模式:
javascript
// 配置:多种国际化匹配模式
const i18nPatterns = [
/\{\{\s*\$?t\s*\(/,
/this\.\$t\s*\(/
]
// 判断一行代码是否已国际化
function isI18nLine(line) {
// 只要匹配任意一个模式,就返回 true
return i18nPatterns.some(pattern => pattern.test(line))
}
// 测试
console.log(isI18nLine('{{ t("username") }}')) // true
console.log(isI18nLine('<div>用户名</div>')) // false
console.log(isI18nLine('this.$t("submit")')) // true
设计思路 :使用 some() 避免手动写多个 if 判断,代码更简洁,扩展性更好。
1.4 与其他方法的区别
| 方法 | 返回值 | 停止条件 | 适用场景 |
|---|---|---|---|
some() |
true/false |
遇到第一个 true 停止 |
检查是否存在 |
every() |
true/false |
遇到第一个 false 停止 |
检查是否全部满足 |
filter() |
新数组 | 遍历全部 | 筛选元素 |
find() |
元素或 undefined |
遇到第一个满足条件停止 | 查找元素 |
二、RegExp.test() - 正则匹配验证
2.1 基本概念
test() 方法用于测试一个字符串是否匹配某个正则表达式模式。
语法:
javascript
regex.test(string)
返回值:
true:字符串匹配正则表达式false:字符串不匹配正则表达式
2.2 基础示例
javascript
// 示例1:检查是否包含数字
const hasNumber = /\d/.test('hello123')
console.log(hasNumber) // true
// 示例2:检查是否为邮箱格式
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
console.log(emailRegex.test('user@example.com')) // true
console.log(emailRegex.test('invalid-email')) // false
// 示例3:检查是否包含中文
const chineseRegex = /[\u4e00-\u9fa5]/
console.log(chineseRegex.test('Hello世界')) // true
console.log(chineseRegex.test('Hello')) // false
2.3 实战场景:检测硬编码文本
在扫描脚本中,我们用 test() 判断字符串是否只包含符号/数字:
javascript
// 判断文本是否只有符号、数字、空白
function isSymbolOnly(text) {
// ^ 开头,[\s\d\W_] 匹配空白、数字、非单词字符、下划线,+ 一个或多个,$ 结尾
return /^[\s\d\W_]+$/.test(text)
}
// 测试
console.log(isSymbolOnly('---')) // true
console.log(isSymbolOnly('123')) // true
console.log(isSymbolOnly('用户名')) // false
console.log(isSymbolOnly('123abc')) // false(包含字母)
正则解析:
^:匹配字符串开头[\s\d\W_]:匹配空白、数字、非单词字符、下划线+:匹配一个或多个$:匹配字符串结尾
2.4 注意事项
javascript
// 1. 正则表达式有 lastIndex 属性
const regex = /abc/g
console.log(regex.test('abc')) // true
console.log(regex.test('abc')) // false(因为 lastIndex 变了!)
// 解决方案:避免使用全局标志或重置 lastIndex
const regex2 = /abc/
console.log(regex2.test('abc')) // true
console.log(regex2.test('abc')) // true
// 2. test() 比 match() 更快(不需要返回匹配结果)
// 适用场景:只需要知道是否匹配,不需要具体内容
三、String.match() - 字符串匹配提取
3.1 基本概念
match() 方法用于在字符串中搜索匹配正则表达式的内容。
语法:
javascript
string.match(regexp)
返回值:
- 有匹配时:返回数组
[0]:完整匹配的字符串[1]、[2]...:捕获组的内容
- 无匹配时:返回
null
3.2 基础示例
javascript
// 示例1:提取邮箱中的用户名和域名
const email = 'user@example.com'
const result = email.match(/^(\w+)@(\w+\.\w+)$/)
console.log(result[0]) // 'user@example.com'(完整匹配)
console.log(result[1]) // 'user'(第一个捕获组)
console.log(result[2]) // 'example.com'(第二个捕获组)
// 示例2:提取所有数字
const text = '订单号:12345,金额:99.00元'
const numbers = text.match(/\d+/g) // 使用全局标志 g
console.log(numbers) // ['12345', '99', '00']
// 示例3:提取 Vue 模板内容
const vueFile = '<template><div>Hello</div></template>'
const templateMatch = vueFile.match(/<template>([\s\S]*?)<\/template>/)
console.log(templateMatch[0]) // '<template><div>Hello</div></template>'
console.log(templateMatch[1]) // '<div>Hello</div>'
3.3 实战场景:提取 Vue 模板
在扫描脚本中,我们用 match() 提取 <template> 标签内的内容:
javascript
function extractTemplate(content) {
const match = content.match(/<template>([\s\S]*?)<\/template>/)
if (!match) return null
// match[0] - 完整匹配:<template>...</template>
// match[1] - 捕获组:模板内部内容
return match[1]
}
// 测试
const vueContent = `
<template>
<div class="container">
<h1>欢迎</h1>
</div>
</template>
<script>export default {}</script>
`
const template = extractTemplate(vueContent)
console.log(template)
// 输出:
//
// <div class="container">
// <h1>欢迎</h1>
// </div>
正则解析 :/<template>([\s\S]*?)<\/template>/
| 部分 | 含义 |
|---|---|
<template> |
匹配开始标签 |
([\s\S]*?) |
捕获组,匹配任意字符(包括换行),非贪婪模式 |
<\/template> |
匹配结束标签(转义 /) |
3.4 全局标志 g 的区别
javascript
// 不使用 g 标志:返回第一个匹配和捕获组
const text = '苹果 10 元,香蕉 8 元'
const match1 = text.match(/(\d+)元/)
console.log(match1) // ['10元', '10', index: 3, ...]
// 使用 g 标志:返回所有匹配(不包含捕获组)
const match2 = text.match(/(\d+)元/g)
console.log(match2) // ['10元', '8元']
四、String.includes() - 子串包含检查
4.1 基本概念
includes() 方法用于检查一个字符串是否包含另一个指定的字符串。
语法:
javascript
string.includes(searchString[, position])
参数:
searchString:要搜索的字符串position(可选):从哪个位置开始搜索,默认为 0
返回值:
true:找到匹配项false:未找到匹配项
4.2 基础示例
javascript
// 示例1:基本用法
const str = 'Hello World'
console.log(str.includes('World')) // true
console.log(str.includes('world')) // false(区分大小写)
console.log(str.includes('Hello', 1)) // false(从索引1开始,找不到Hello)
// 示例2:检查文件扩展名
const filename = 'image.png'
if (filename.includes('.png') || filename.includes('.jpg')) {
console.log('是图片文件')
}
// 示例3:检查 URL 参数
const url = 'https://example.com?page=1&sort=asc'
console.log(url.includes('sort=asc')) // true
4.3 实战场景:跳过调试代码
在扫描脚本中,我们用 includes() 判断是否需要跳过某些函数调用:
javascript
const ignoreFunctions = [
'console.log', 'console.warn', 'console.error',
'alert', 'confirm', 'prompt'
]
function isIgnoredLine(line) {
return ignoreFunctions.some(func => line.includes(func))
}
// 测试
console.log(isIgnoredLine('console.log("debug")')) // true
console.log(isIgnoredLine('alert("操作成功")')) // true
console.log(isIgnoredLine('this.$t("submit")')) // false
4.4 与其他方法的区别
| 方法 | 返回值 | 是否支持正则 | 适用场景 |
|---|---|---|---|
includes() |
true/false |
❌ | 精确子串匹配 |
indexOf() |
索引或 -1 |
❌ | 需要知道位置 |
search() |
索引或 -1 |
✅ | 正则匹配位置 |
test() |
true/false |
✅ | 正则验证 |
五、综合实战:硬编码扫描器
将四个方法组合起来,实现一个简化版的硬编码检测器:
javascript
// 配置
const CONFIG = {
i18nPatterns: [/\{\{\s*\$?t\s*\(/, /this\.\$t\s*\(/],
ignoreFunctions: ['console.log', 'alert']
}
// 判断是否已国际化
function isI18nLine(line) {
return CONFIG.i18nPatterns.some(pattern => pattern.test(line))
}
// 判断是否忽略
function isIgnoredLine(line) {
return CONFIG.ignoreFunctions.some(func => line.includes(func))
}
// 判断是否纯符号
function isSymbolOnly(text) {
return /^[\s\d\W_]+$/.test(text)
}
// 扫描一行 JS 代码
function scanLine(line, filePath, lineNum) {
if (isI18nLine(line)) return null
if (isIgnoredLine(line)) return null
const stringRegex = /['"`]([^'"`]*[\u4e00-\u9fa5]+[^'"`]*)['"`]/g
const match = stringRegex.exec(line)
if (match && match[1] && !isSymbolOnly(match[1])) {
return {
file: filePath,
line: lineNum,
text: match[1]
}
}
return null
}
// 测试
const testCode = `
const msg = '操作成功'
console.log('debug')
this.$t('submit')
const title = "确认删除?"
`
const lines = testCode.split('\n')
lines.forEach((line, idx) => {
const result = scanLine(line, 'test.js', idx + 1)
if (result) {
console.log(`发现硬编码: ${result.text} at line ${result.line}`)
}
})
// 输出:
// 发现硬编码: 操作成功 at line 2
// 发现硬编码: 确认删除? at line 5
练习题
练习1:Array.some()
题目 :实现一个函数 hasPermission(roles, requiredRoles),检查用户角色数组中是否至少包含一个所需角色。
javascript
// 测试用例
console.log(hasPermission(['admin', 'user'], ['admin'])) // true
console.log(hasPermission(['user', 'guest'], ['admin'])) // false
console.log(hasPermission(['manager', 'user'], ['admin', 'manager'])) // true
参考答案
javascript
function hasPermission(roles, requiredRoles) {
return requiredRoles.some(role => roles.includes(role))
}
练习2:RegExp.test()
题目 :实现一个函数 isValidPhone(phone),验证手机号格式(11位数字,以1开头)。
javascript
// 测试用例
console.log(isValidPhone('13812345678')) // true
console.log(isValidPhone('12345678901')) // false(不以1开头)
console.log(isValidPhone('1381234567')) // false(不足11位)
console.log(isValidPhone('138123456789')) // false(超过11位)
参考答案
javascript
function isValidPhone(phone) {
return /^1\d{10}$/.test(phone)
}
// 正则解析:^1 开头,\d{10} 10个数字,$ 结尾
练习3:String.match()
题目 :实现一个函数 extractTags(content),提取字符串中所有的 #标签 格式的标签(以#开头,后跟中文或英文)。
javascript
// 测试用例
const content = '今天天气真好 #晴天 适合出去玩 #周末'
console.log(extractTags(content)) // ['晴天', '周末']
const content2 = '#JavaScript #编程学习 太棒了'
console.log(extractTags(content2)) // ['JavaScript', '编程学习']
参考答案
javascript
function extractTags(content) {
const matches = content.match(/#([\u4e00-\u9fa5a-zA-Z]+)/g)
if (!matches) return []
return matches.map(tag => tag.slice(1)) // 去掉 #
}
练习4:String.includes()
题目 :实现一个函数 filterByKeyword(items, keyword),筛选出数组中包含指定关键词的字符串(不区分大小写)。
javascript
// 测试用例
const items = ['Hello World', 'JavaScript', 'HELLO everyone', 'Goodbye']
console.log(filterByKeyword(items, 'hello')) // ['Hello World', 'HELLO everyone']
console.log(filterByKeyword(items, 'script')) // ['JavaScript']
参考答案
javascript
function filterByKeyword(items, keyword) {
const lowerKeyword = keyword.toLowerCase()
return items.filter(item =>
item.toLowerCase().includes(lowerKeyword)
)
}
练习5:综合应用
题目 :实现一个函数 findHardcodedText(code),检测代码中是否包含硬编码的中文字符串(不包括注释和已国际化的代码)。
检测规则:
- 跳过以
//开头的注释行 - 跳过包含
$t(或t(的行 - 匹配单引号或双引号中的中文字符串
javascript
// 测试用例
const code1 = `
// 这是注释
const msg = '操作成功'
this.$t('submit')
`
const code2 = `
const title = "确认删除?"
console.log('调试信息')
`
console.log(findHardcodedText(code1)) // []
console.log(findHardcodedText(code2)) // ['操作成功', '确认删除?']
参考答案
javascript
function findHardcodedText(code) {
const results = []
const lines = code.split('\n')
lines.forEach(line => {
// 跳过注释
if (line.trim().startsWith('//')) return
// 跳过已国际化的行
if (/\$t\(/.test(line) || /t\(/.test(line)) return
// 匹配中文字符串
const matches = line.match(/['"`]([^'"`]*[\u4e00-\u9fa5]+[^'"`]*)['"`]/g)
if (matches) {
matches.forEach(match => {
const text = match.slice(1, -1) // 去掉引号
results.push(text)
})
}
})
return results
}
总结
| 方法 | 用途 | 返回类型 | 典型场景 |
|---|---|---|---|
some() |
数组条件检测 | boolean |
检查是否存在满足条件的元素 |
test() |
正则匹配验证 | boolean |
验证格式、判断是否匹配 |
match() |
字符串匹配提取 | array/null |
提取内容、解析数据 |
includes() |
子串包含检查 | boolean |
精确字符串查找 |
学习建议:
- 动手写每个练习题,不要只看答案
- 在浏览器控制台或 Node.js 中实验
- 结合你的项目实际场景,尝试用这些方法解决真实问题
掌握这四个方法,足以应对日常开发中 80% 的字符串和数组操作场景!