大家好,欢迎来到IT知识分享网。
压缩的核心原理其实主要是三个
- 移除注释
- 缩短标识符
- 压缩空白符
一、移除注释
// 1. 移除注释 let result = code .replace(/\/\*[\s\S]*?\*\//g, '') // 多行注释 .replace(/\/\/.*$/gm, ''); // 单行注释
代码解释
这段代码是用来移除 JavaScript 代码中的注释的,使用了两个正则表达式替换:
- 第一个 .replace() 移除多行注释(/* … */):
- 正则表达式:/\/\*\s\S*?\*\//g
- 解释: \/\* 匹配 /* 开始符号 \s\S*? 非贪婪匹配任意字符(包括换行) \*\/ 匹配 */ 结束符号
- g 标志表示全局匹配
- 第二个 .replace() 移除单行注释(// …):
- 正则表达式:/\/\/.*$/gm
- 解释: \/\/ 匹配 // .* 匹配后面的所有字符直到行尾 $ 匹配行尾
- gm 标志表示全局和多行匹配
示例: javascript const code = ` // 单行注释 function test() { /* 多行 注释 */ return 1; } `; const result = code .replace(/\/\*\s\S*?\*\//g, '') .replace(/\/\/.*$/gm, ''); console.log(result); /* 输出: function test() { return 1; } */
/s和/S分别表示
在正则表达式中,\s 和 \S 是两个常用的元字符,它们分别表示:
- \s(小写 s)
- 含义:匹配任何空白字符(whitespace character)
- 包括: 空格 制表符 \t 换行符 \n 回车符 \r 垂直制表符 \v 换页符 \f
- \S(大写 S)
- 含义:匹配任何非空白字符(non-whitespace character)
- 相当于:^\s(即不是 \s 的字符)
示例对比 javascript
const str = "Hello\tWorld\n123"; // 匹配所有空白字符 console.log(str.match(/\s/g)); // 输出: "\t", "\n" (制表符和换行符) // 匹配所有非空白字符 console.log(str.match(/\S/g)); // 输出: "H", "e", "l", "l", "o", "W", "o", "r", "l", "d", "1", "2", "3"
在原始问题中的应用
在最初的代码中: javascript
.replace(/\/\*\s\S*?\*\//g, '') - `\s\S` 是一个巧妙用法,表示匹配所有字符(包括换行符): - `\s` 匹配空白字符(如换行符) - `\S` 匹配非空白字符 - 组合起来等价于 `.`(点号)但能匹配换行符(因为普通的 `.` 默认不匹配换行符)
这种写法比 /\/\*.*?\*\//gs(使用 s 标志让 . 匹配换行符)更兼容旧版 JavaScript 环境。
[\s\S]*? 非贪婪匹配是什么
非贪婪匹配(Lazy/Lenient Matching) 在正则表达式中,贪婪匹配(Greedy Matching) 和 非贪婪匹配(Lazy Matching) 是两种不同的匹配策略:
- 贪婪匹配(默认):尽可能匹配最长的字符串。
- 非贪婪匹配:尽可能匹配最短的字符串。
- 如何表示非贪婪匹配?
在量词(*, +, ?, {n,m})后面加上 ?,就变成了非贪婪模式:
量词 |
贪婪模式 |
非贪婪模式 |
* |
.* |
.*? |
+ |
.+ |
.+? |
? |
??(极少用) |
??(极少用) |
{n,m} |
{n,m} |
{n,m}? |
- 示例对比 示例 1:匹配 HTML 标签
html
<div>Hello</div><div>World</div>
(1) 贪婪匹配(`<div>.*</div>`)
javascript
"<div>Hello</div><div>World</div>".match(/<div>.*<\/div>/);
// 匹配整个字符串:
// "<div>Hello</div><div>World</div>"
(2) 非贪婪匹配(`<div>.*?</div>`)
javascript
"<div>Hello</div><div>World</div>".match(/<div>.*?<\/div>/);
// 只匹配第一个 `<div>`:
// "<div>Hello</div>"
示例 2:移除多行注释 在最初的代码中: javascript
.replace(/\/\*\s\S*?\*\//g, '') - `\s\S*?` 表示非贪婪匹配任意字符(包括换行),直到遇到第一个 `*/`。 - 如果不加 `?`(贪婪模式),它会匹配从第一个 `/*` 到最后一个 `*/` 之间的所有内容,可能会错误地吃掉多个注释块。
- 何时使用非贪婪匹配?
✅ 适用场景:
- 提取最短匹配的内容(如 HTML/XML 标签、注释块)。
- 避免匹配过多内容(如 .* 默认会匹配到最后一个符合条件的字符)。
❌ 不适用场景:
- 需要匹配到最后一个符合条件的字符时(如提取整个 JSON 字符串)。
二、缩短标识符(基本版)
const varMap = new Map(); let varCount = 0; // 匹配变量声明 result = result.replace( /\b(var|let|const|function)\s+([a-zA-Z_$][\w$]+)/g, (match, keyword, varName) => { if (!varMap.has(varName)) { varMap.set(varName, `v${varCount++}`); } return `${keyword} ${varMap.get(varName)}`; } );
代码解析
这段代码的作用是匹配 JavaScript 变量声明(var/let/const/function),并将变量名替换成一个简短的、自动生成的名称(如 v0, v1, v2…),通常用于代码混淆(Obfuscation)或缩小变量名的场景。
/\b(varletconstfunction)\s+(a-zA-Z_$\w$+)/g - `\b`:匹配单词边界(防止匹配到类似 `myvar` 这样的单词)。 - `(var let const function)`:匹配变量声明关键字(`var`、`let`、`const` 或 `function`)。 - `\s+`:匹配至少一个空白字符(如空格、制表符)。 - `(a-zA-Z_$\w$+)`:匹配变量名: - `a-zA-Z_
手把手写JavaScript压缩的核心原理,不信你还学不会 - 今日头条 :变量名必须以字母、`_` 或 `
手把手写JavaScript压缩的核心原理,不信你还学不会 - 今日头条 开头。 - `\w$+`:后续字符可以是字母、数字、`_` 或 `手把手写JavaScript压缩的核心原理,不信你还学不会 - 今日头条 。
- 替换函数 javascript替换函数 javascript
(match, keyword, varName) => { if (!varMap.has(varName)) { varMap.set(varName, `v${varCount++}`); } return `${keyword} ${varMap.get(varName)}`; } - 参数: - `match`:整个匹配到的字符串(如 `let myVar`)。 - `keyword`:匹配到的关键字(如 `let`)。 - `varName`:匹配到的变量名(如 `myVar`)。 - 逻辑: 1. 检查 `varMap`(可能是一个 `Map` 或对象)是否已存储该变量名。 2. 如果没有,则生成一个新名称(如 `v0`, `v1`),并存入 `varMap`。 3. 返回替换后的字符串(如 `let v0`)。
示例 输入代码
let myVar = 10; const myConst = "Hello"; function myFunc() {} 处理后 let v0 = 10; const v1 = "Hello"; function v2() {} (假设 `varCount` 从 `0` 开始)
三、压缩空白符
// 3. 压缩空白符 result = result .replace(/\s+/g, ' ') // 多空格合并 .replace(/\s*([={}[\](),;:])\s*/g, '$1') // 清除运算符周围空格 .replace(/;}/g, '}'); // 结尾分号清除 return result; }
这段代码的作用是压缩 JavaScript 代码中的空白符,以减少文件大小并提高加载速度。它主要做了三件事:
- 合并多个连续空格为单个空格
- 清除运算符和符号周围不必要的空格
- 移除 ;} 中的分号(因为 } 前不需要分号)
代码解析
- replace(/\s+/g, ‘ ‘)
- 正则表达式:/\s+/g \s+:匹配一个或多个空白字符(包括空格、换行符、制表符等)。
- 替换:’ ‘ 将所有连续的空白符替换成单个空格。
示例: javascript
"Hello World\n\nGoodbye" → "Hello World Goodbye"
- replace(/\s*(,;:)\s*/g, ‘$1’)
- 正则表达式:/\s*(,;:)\s*/g \s*:匹配零个或多个空白字符(可选)。 (,;:):匹配以下符号: =(赋值) {}(大括号、方括号、圆括号) ,;:(逗号、分号、冒号) \s*:再次匹配零个或多个空白字符(可选)。
- 替换:’$1′ 只保留符号本身,删除其前后的所有空格。
示例: javascript
"let x = 1 ;" → "let x=1;" "if ( x === y ) {" → "if(x===y){"
完整示例
javascript function test ( ) { let x = 1 ; if ( x === 2 ) { return "Hello" ; } }
处理后
javascript
function test(){let x=1;if(x===2){return "Hello"}}
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/185048.html