
文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载eval是 JavaScript 内置的代码字符串执行器在本仓库《现代 JavaScript 教程》的 eval-calculator 任务 中它被用来把用户输入的一行算术表达式如2*32直接计算并返回结果。读完本文你将掌握eval(code)的执行语义、它在词法环境与严格模式下的行为差异以及如何用正则表达式把任意代码执行收窄为仅限数字与运算符的安全计算器并了解window.eval与new Function这两种现代替代方案。任务背景一个三行代码的计算器仓库中的任务原文见 task.md非常直接创建一个计算器弹出提示框让用户输入一个算术表达式然后返回计算结果并且明确说明无需检查表达式的正确性直接求值并返回结果即可。官方给出的 解法 精简到极致let expr prompt(Type an arithmetic expression?, 2*32); alert( eval(expr) );运行后用户在prompt中输入2*32eval立即把它当作代码求值alert弹出8。这短短三行就是整个任务的核心用eval把字符串形式的数学表达式变成真实计算结果省去了手写解析器、中缀转后缀等全部工作。eval 的执行语义为什么它能算出表达式要理解上面的代码为何成立需要先弄清eval的本质。本仓库的 《Eval: run a code string》章节 给出了权威定义eval用于执行一段字符串形式的代码语法为let result eval(code);以下几个特性直接决定了计算器能否工作1. 返回值为最后一条语句的执行结果。这正是eval(11)返回2的原因let value eval(11); alert(value); // 2let value eval(let i 0; i); alert(value); // 1所以eval(expr)会把表达式字符串当作一条语句执行并返回其值——算术表达式恰好满足这一语义。2. 代码字符串长度不限。它可以是多行文本可以包含函数声明、变量声明等不只是简单表达式。这一点既是能力也是风险来源。3. 在当前词法环境中执行。eval 的代码能看到并操作外层变量let a 1; function f() { let a 2; eval(alert(a)); // 2看到的是函数内部的 a } f();它甚至可以修改外层变量let x 5; eval(x 10); alert(x); // 10值被修改了4. 严格模式下拥有独立的词法环境。在use strict中eval 内部声明的函数和变量对外不可见本教程的可运行示例默认启用严格模式eval(let x 5; function f() {}); alert(typeof x); // undefined不存在该变量 // 函数 f 同样不可见若没有use stricteval 没有独立词法环境x和f就会泄漏到外层。安全隐患用户输入的是任意代码不只是数字解法文档紧接着给出了一个至关重要的警示用户实际上可以输入任何文本或代码。把上面的计算器稍作变化输入alert(hacked)、while(true){}或process之类的字符串eval都会老老实实去执行——因为它在设计上就是执行任意代码字符串。这正是社区流传eval is evil的原因详见 eval 章节的 Using eval 小节安全层面eval把不可信输入变成代码执行点是典型任意代码注入code injection入口。用户输入的任何字符串都会被当作程序运行。工程层面eval 能访问外层局部变量这会带来副作用——代码压缩工具minifier在压缩时会安全地把局部变量重命名为a、b等短名但一旦存在eval这些变量可能被 eval 内的代码字符串引用minifier 就不敢对它们改名从而损害压缩率。维护层面在 eval 字符串内部使用外层局部变量属于不良编程实践会让代码更难维护、更难追踪。因此现代 JavaScript 中几乎不再需要 eval它曾是弱语言时代的万能工具如今基本都能被现代语言特性或 JavaScript Module 替代。安全加固用正则把表达式圈在算术范围内解法文档给出的加固思路是用正则表达式检查expr使其只允许包含数字和运算符。也就是说在把字符串交给eval之前先用模式匹配把它的内容限制在0-9与算术运算符集合内从源头排除函数调用、语句、标识符等可执行代码。由于原文档只给出思路、未给出具体正则下面给出一种与本仓库正则表达式章节配套的落地实现——白名单式校验只放行数字、四则运算符、括号、小数点与空白let expr prompt(Type an arithmetic expression?, 2*32); if (!/^[0-9\-*/().\s]$/.test(expr)) { alert(Invalid expression: only digits and operators are allowed); } else { alert(eval(expr)); }逐段解读这个正则片段含义^...$锚定整个字符串要求从头到尾全部匹配杜绝部分匹配漏网[0-9\-*/().\s]字符集数字0-9、加号、减号\-转义避免被当作范围符、乘号、除号、左右括号、小数点、空白字符集内至少出现一次也可用*允许空串校验通过后表达式里只可能是数字、运算符、括号和小数点即使拼接成12*(34)/2这类组合eval执行的也始终是纯算术代码无法注入alert、while或标识符。需要说明的是这只是一种合理实现建议本任务并不要求校验表达式的正确性如除零、括号不配对只要求把输入收窄到算术语法这与 task.md 的无需检查正确性的定位一致。另一种等价的加固思路是黑名单式拒绝[a-zA-Z]、、;等可疑字符但白名单更稳健因为它只承认明确安全的字符集合。若对正则语法本身需要复习可直接参考仓库的 正则表达式系列章节。现代替代方案window.eval 与 new Function即便要使用 evaleval 章节 也给出了两条规避访问外层变量副作用的安全用法方案一如果 eval 的代码不使用外层变量用window.eval(...)调用让代码在全局作用域执行与外层词法环境彻底隔离let x 1; { let x 5; window.eval(alert(x)); // 1读到的是全局变量 }方案二如果 eval 的代码需要局部数据改用new Function并把数据作为参数显式传入let f new Function(a, alert(a)); f(5); // 5new Function的完整机制见本仓库 《The new Function syntax》章节它同样能从字符串创建函数但其[[Environment]]指向全局词法环境而非当前词法环境因此天然无法访问外层局部变量把数据作为参数显式传递架构上更清晰也完全不受 minifier 改名的影响。回到计算器场景如果要计算的表达式来自不可信的服务器或远端且需要传入上下文数据更安全的做法是function createSafeCalc(a, b) { return new Function(a, b, return a b); } let sum createSafeCalc(2, 3); alert(sum()); // 5 —— 通过参数显式传值而非依赖 eval 读取外层变量完整示例从朴素版到安全版将任务与解法、加固方案合并得到一套完整的、可直接在本仓库环境运行的安全算术计算器// 朴素版仅演示 eval 的能力不做任何防护 let expr1 prompt(Type an arithmetic expression?, 2*32); alert(eval(expr1)); // 任意代码都会被执行危险 // 安全版白名单正则 eval let expr2 prompt(Type an arithmetic expression?, 2*32); if (!/^[0-9\-*/().\s]$/.test(expr2)) { alert(Invalid expression: only digits and operators are allowed); } else { alert(eval(expr2)); }关于算术运算符本身、-、*、/、%、**的优先级与结合规则可回溯本仓库的 《Basic operators, maths》章节 作为前置知识。总结围绕 Eval-calculator 任务 与 官方解法可以提炼出如下要点任务本质用eval(expr)把用户输入的算术表达式字符串直接求值核心代码只有 prompt eval alert 三行。eval 的行为eval(code)执行代码字符串并返回最后一条语句的结果代码在当前词法环境中执行、可读写外层变量严格模式下拥有独立词法环境。核心教训eval执行的是任意代码用户输入必须经过白名单正则校验仅允许数字与运算符后才可求值。现代替代在全局作用域求值用window.eval(code)需要传入外部数据时用new Function显式传参见 new Function 章节。eval是理解 JavaScript字符串即代码模型的最佳窗口但生产代码中请记住本章的核心结论很少用到、可访问外层变量、优先用window.eval或new Function替代——这也是本仓库 eval 章节 想传达的完整信息。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐Alpine 的 CSP 兼容构建alpinejs/csp在无 unsafe-eval 环境下安全使用表达式Alpine 的 CSP 兼容构建alpinejs/csp在无 unsafe eval 环境下安全使用表达式 导读 本文聚焦 Alpine 官方提供的前端JavaScript 表达式求值器更安全的数学计算神器JavaScript 表达式求值器更安全的数学计算神器 在这个高度数字化的时代JavaScript 已经成为网页开发和服务器端编程的重要语言而数学计算则是使用 ANTLR4 构建算术表达式语法arithmetic 文法全面解析使用 ANTLR4 构建算术表达式语法arithmetic 文法全面解析 导读 本文以 grammars v4 仓库中的 arithmetic 文法 http编程语言编译器开发工具上一篇Handy 离线语音转文字3 步跑通开口说话文字直接出现音频不出电脑下一篇DBeaver连接配置加密算法选择安全与性能平衡的加密方式创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考