手把手写JavaScript压缩的核心原理,不信你还学不会

手把手写JavaScript压缩的核心原理,不信你还学不会压缩的核心原理其实主要是三个移除注释缩短标识符压缩空白符一 移除注释 1 移除注释 let result code replace s S g 多行注释 replace

大家好,欢迎来到IT知识分享网。

压缩的核心原理其实主要是三个

  1. 移除注释
  2. 缩短标识符
  3. 压缩空白符

一、移除注释

// 1. 移除注释 let result = code .replace(/\/\*[\s\S]*?\*\//g, '') // 多行注释 .replace(/\/\/.*$/gm, ''); // 单行注释

代码解释

这段代码是用来移除 JavaScript 代码中的注释的,使用了两个正则表达式替换:

  1. 第一个 .replace() 移除多行注释(/* … */):
  2. 正则表达式:/\/\*\s\S*?\*\//g
  3. 解释: \/\* 匹配 /* 开始符号 \s\S*? 非贪婪匹配任意字符(包括换行) \*\/ 匹配 */ 结束符号
  4. g 标志表示全局匹配
  5. 第二个 .replace() 移除单行注释(// …):
  6. 正则表达式:/\/\/.*$/gm
  7. 解释: \/\/ 匹配 // .* 匹配后面的所有字符直到行尾 $ 匹配行尾
  8. 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 是两个常用的元字符,它们分别表示:

  1. \s(小写 s)
  • 含义:匹配任何空白字符(whitespace character)
  • 包括: 空格 制表符 \t 换行符 \n 回车符 \r 垂直制表符 \v 换页符 \f
  1. \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) 是两种不同的匹配策略:

  • 贪婪匹配(默认):尽可能匹配最长的字符串。
  • 非贪婪匹配:尽可能匹配最短的字符串。

  1. 如何表示非贪婪匹配?

在量词(*, +, ?, {n,m})后面加上 ?,就变成了非贪婪模式:

量词

贪婪模式

非贪婪模式

*

.*

.*?

+

.+

.+?

?

??(极少用)

??(极少用)

{n,m}

{n,m}

{n,m}?


  1. 示例对比 示例 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*?` 表示非贪婪匹配任意字符(包括换行),直到遇到第一个 `*/`。 - 如果不加 `?`(贪婪模式),它会匹配从第一个 `/*` 到最后一个 `*/` 之间的所有内容,可能会错误地吃掉多个注释块。
  1. 何时使用非贪婪匹配?

✅ 适用场景:

  • 提取最短匹配的内容(如 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压缩的核心原理,不信你还学不会 - 今日头条
  1. 替换函数 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 代码中的空白符,以减少文件大小并提高加载速度。它主要做了三件事:

  1. 合并多个连续空格为单个空格
  2. 清除运算符和符号周围不必要的空格
  3. 移除 ;} 中的分号(因为 } 前不需要分号)

代码解析

  1. replace(/\s+/g, ‘ ‘)
  • 正则表达式:/\s+/g \s+:匹配一个或多个空白字符(包括空格、换行符、制表符等)。
  • 替换:’ ‘ 将所有连续的空白符替换成单个空格。

示例: javascript

"Hello World\n\nGoodbye" → "Hello World Goodbye"
  1. 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

(0)
上一篇 2025-08-05 12:10
下一篇 2025-08-05 12:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信