当前位置: 首页 > news >正文

【每日积累】javascript 一文弄懂eval

eval 动态化执行语句

概述

eval方法是javascript的全局方法,能够执行含有javascript代码的字符串,虽然eval方法带来强大的动态执行功能,但考虑其负面影响,建议少用,在特殊情况下可以使用eval方法动态改变代码的执行作用域来达到代码的灵活性

动态值,表达式和语句

  console.log(typeof eval('true')) // booleanconsole.log(typeof eval("'9'")) // stringconsole.log(typeof eval('8')) // number

注意点:

  • 如果参数code 含有一个表达式,则计算该表达式并返回该计算值
    console.log(eval('1+1')); // 2
  • 如果参数code 含有一个或者多个javascript语句,则eval方法将执行这些语句
    console.log(eval('1+1')); // 2console.log(eval('8'))  // 单值表达式console.log(eval('8;')) // 单值语句//虽然它们语义不一样,但还是按照js的词法结构在解释器进行解析
  • 为了预防不可预知的错用,同时考虑到实现效率的问题。在ESv3 标准中,给eval加了禁制,不能将eval赋值给另一个属性,然后在代码里面灵活调用和禁止用户覆盖eval属性
   // es3 中let e = eval;console.log(e('8')) //  Evalerror 异常// 目前let e = eval;console.log(e('8+9')); // 17
  • 如果最后一个语句有返回值,则eval则返回这个值
  • 如果参数code 没有返回任何值,则eval返回undefined
    在js中,除了空语句和命令语句之外,一般语句都会有返回值,返回值由执行最后一个子语句或表达式的值决定
    let s = "for (let index = 0; index < 50; index++) { console.log(index);}"// 上面语句会执行 依次打印对应的index 0-49console.log(eval(s)) // undefined 说明eval总会将代码执行的值进行返回,如果没有就返回undefined// 
  • 如果参数code抛出异常,则eval会将异常传递给调用者。
 try {let s = "for (let index = 0; index < 50; index++) { ;}"console.log(eval(s)) // undefined} catch (error) {console.log(error.message); // 返回错误信息}
  • 大部分字符串参数的javascript函数和方法都会接受其他的参数,在继续操作之前把参数强制转换成字符串,但eval方法比较特殊,code参数如果不是原始的字符串,则eval不做任何处理并返回原始值。当传递给eval原始字符串值时,不要传递字符串对象。
    例如:
  let s = new String('1+2') // string 对象console.log(eval(s)); // 返回字符串“1+2”let s1 = "1+2"; // 原始的直接量console.log(eval(s1)) // 3console.log(typeof eval(s1)) // 返回为number类型

对象和函数直接量的歧义问题

  • eval方法能够很轻松地执行普通表达式或者语句,并返回对应的返回值,而在计算下方code则会返回异常产生歧义
    var o = '{user:"c88",pass:"123456"}';console.log(eval(o)) // thorw error
  • 或许你会产生上面表达式是否有错误,其实并没有,如果我们只定义一个属性却是正确的,则就表明对象产生对应的歧义问题!
    var b = '{user:"c88"}';console.log(eval(b)) // c88// 我们平时生成obj对象是 obj = { age : 12 , str:'123' } //key 必须都是字符串,这是正确对象字面量的解析,产生歧义部分的问题:

上述产生歧义是复合语句和冒号导致 为了避免这种歧义采用下方code:

  var o = '({user:"c88",pass:"123456"})';console.log(eval(o)) //{user: 'c88', pass: '123456'}
  • function 也属于一种对象的表达形式,所以要通过function来进行处理字面量也需要避免歧义
    var o = "(function(){ return 8 })()"  console.log(8)orvar o = "(function(){return 8}())" console.log(8)orvar o = "function(){return 8}"console.log(eval("("+o+"())")) // 个人感觉不怎么推荐。
  • 对于数组对象,则不需要考虑上诉情况可以直接进行使用。
    var o = '["123","7777"][0]' console.log(o) // 123

eval全局执行域及其兼容

  • 关于eval全局执行域是在javascript环境中,而javascript代码又必须在一定的环境进行运行,如全局域和局部域,这里的执行域我个人理解为特定的环境,貌似任何都离不开宿主这个词。对于被动态执行的code来说,这个问题就较为复杂,比如eval将在全局域中执行还是局部域之行。如下code example:
    var n  = 1; // global function f(){var n= 3;eval('n=5') // local // 如果想覆盖全局变量window.eval('n=5') //  则下方全局就打印 5console.log(n) // 5}f();console.log(n) //  1

eval当前执行域

  • 看上述例子可以看到,eval在全局执行的时候只会影响同名声明的变量,在函数里面声明只会影响当前作用域的同名变量,外部和内部域是隔离开来的!
    eval("var n = 1");function f(){eval("var n = 2");console.log(n) //2}f();console.log(n) //1
http://www.hskmm.com/?act=detail&tid=35487

相关文章:

  • 量子计算25年发展历程与技术挑战
  • 腾讯云COS通过CDN加速配置指南 - 教程
  • 前端: 如何优化列表大批量的数据渲染
  • 【模块化解读】commonjs vs commonjs2 exports vs module.exports
  • 【GitHub每日速递 251021】一键将全新Arch安装变身超美现代Web开发系统!Omarchy太神了
  • 藏宝阁
  • [Mongodb]mongodb的安装以及增删改查
  • PHP 8.5 新特性 闭包可以作为常量表达式了
  • 【JavaScript-基础】split,splice,slice 三者的用法
  • 2025 代码源 CSP-S 模拟赛复盘
  • 2025.10.21——1绿
  • 【JavaScript-基础】map、forEach、for、for in、for of等的区别
  • dotnet 利用 Windows 注册表实现开机自动启动
  • 使用uWSGI和Nginx部署深度学习模型指南
  • 帮我回答这些问题
  • Python 类属性的应用场景
  • 为什么很多人分不清关联和聚合?
  • 机器学习商业应用实战指南
  • 在线签名工具,手写签名保存为png图片,用于生成电子签名用于word文档等
  • 什么情况下,有必要将属性设为类属性而非实例属性?
  • 在线签名工具,保存为png图片,用于生成电子签名用于word文档等
  • 玄机——第五章 Windows 实战-evtx 文件分析
  • CityRefer:城市规模点云数据上的地理感知 3D 视觉接地数据集 - MKT
  • SensatUrban语义分割数据集SensatUrban - MKT
  • 推荐算法参考资料
  • LLM学习笔记DAY8
  • 软件工程第二次团队作业——构建一个智能体
  • VoxelNeXt 用于 3D 对象检测和跟踪的完全稀疏 VoxelNet(CVPR 2023) - MKT
  • CityNav:包含地理信息的语言目标空中导航数据集 - MKT
  • Grounded-SAM 使用文本提示检测和分割所有内容 - MKT