【趣味JavaScript】我的天! 居然工作了5年的前端开发都不知道eval函数其中居然暗藏玄机!

news2024/12/23 6:55:01

🚀 个人主页 极客小俊
✍🏻 作者简介:web开发者、设计师、技术分享博主
🐋 希望大家多多支持一下, 我们一起进步!😄
🏅 如果文章对你有帮助的话,欢迎评论 💬点赞👍🏻 收藏 📂加关注

eval()函数介绍

首先你要知道在JSeval()函数是用来干嘛的!

它主要的功能就是将一个JS字符串解析,然后把它作为脚本代码来执行, 要知道字符串始终就是字符串是不能被直接执行的!

有了eval()函数就可以做到, 它的使用语法也很简单!

eval(字符串参数);

参数解释

传递的参数其实是要执行的 JavaScript代码字符串形式!

它的返回值也就是通过计算字符串得到可执行JS代码脚本

举个栗子

这里有一段代码

var code='var x=10;var y=20;console.log(x*y)';

如果直接执行或打印上面的code变量 那么只能直接输出这个字符串

如图

并且从字符串中的内容上看,很明显是一段JS代码

那么我们就可以使用eval()函数 来让它变成一个可执行的JS脚本

代码如下

var code='var x=10;var y=20;console.log(x*y)';
eval(code);

如图

eval()函数特别的使用方法以及原理

按照以上这样操作,我们只要把可执行的JS字符串丢给eval()函数不就行了吗?

那为什么有些时候还要加什么小括号()?

也就是为什么还要加()变成 eval('('+变量名+')')呢? 很多新手会在这里犯困惑!

那是因为如果字符串中的语法不正确,eval() 函数会抛出语法错误

w3c文档上也有明确的说明

如图

那到底如何来理解这个意思呢? 什么叫不是合法的表达式和语句呢?

举个栗子

var data ='{"张三"}';
console.log("类型为:"+typeof data);
console.log(eval(data));

以上打印结果如下图:

但是如果我写成以下这样就会给你报一个SyntaxError语法错误的提示!

如图

可是你可能会想,这不就是我们常见的JSON数据吗,虽然是字符串, 不能直接使用,但是使用eval()函数处理以下应该可以直接调用了呀,可为什么会报错呢?

原理分析

首先JSON是一种数据格式,它用于存储交换数据用的,这没问题吧!

JSON中,数据被表示为键值对,这里的之间用冒号分隔,键值对之间用逗号分隔

并且整个数据被包含在大括号{}当中,这也是JSON数据格式标准 也没问题对吧!

可是呢eval()函数会把这个字符串{......}当成一个Javascript语句块来处理, 那么显然这样解析就会报错!

我们平常写JS语句块都是以下的方式

for(){
    ..语句块..
}

if(){
    ..语句块..
}

while(){
    ..语句块..
}

这些都是语句块,也可以叫复合语句块

复合语句块是指由多个语句组成的语句块,它们通常被包含在一对花括号{....}

在开发中,复合语句块通常用于控制程序的流程

例如上面说到的: if、for、while 等语句的语句体就是一个复合语句块

复合语句块可以包含变量定义、表达式、控制语句等多种语句,

这些语句将按照顺序依次执行,直到复合语句块的结尾处!

那么你有见过以下这样的复合语句块块吗?

{
    "username":"zhangsan"
}

我们来运行看看效果

如图

那么很明显,从JS基本复合语句块的语法上,这就不能这样写对吧! 从JS语句的语法上讲不通呀!

所以说刚刚我们目的是让 eval()函数JSON字符串解析为一个对象,而不是解析为语句块 明白了吧!

你也可以理解为是一种强制性的转换成表达式来进行表示!

如果我们不加括号,那么eval()函数就可能会将 这个JSON字符串解析为JS语句块的形式来进行执行,那语句块按照这样取写肯定是错误的语法呀,从而抛出语法错误!

那么就像上面的案例一样我们也可以让它正常执行成为一个JSON对象

代码如下

({
    "username":"zhangsan"
})

给它加上一个()括号 嗯嗯 这里非常的精妙!

加了()括号以后就表示一个整体, 让JS引擎知道这是一个JSON对象而非一个语句块, 自然就不会报错了!

我们也可以赋值给一个变量,把这个JSON对象保存起来进行调用了!

var test=({
    "username":"zhangsan"
});
console.log(test.username);

如图

所以{..}这种对象写法形式,不加外层的小括号,会被识别为JS代码块开始结束标记

注意

那这个时候可能就有人要问了, 为什么我不加这个小括号()也可以正常执行这个JSON对象呢?

代码如下

var test={"username":"zhangsan"};
console.log(test.username);

如图

分析解释

对,根据JSON的语法定义上来说这是没错, 并且你也把这一个整体赋值给了一个变量进行保存!

这跟加一个小括号() 一个道理, 明白了吧! JS引擎没有单一的把这{...}中的内容看成是一个语句块

而是把这一堆东西,赋值给了一个变量成为整体!

eval()函数使用心得体会

到这里你再次去理解eval()函数在处理字符串的时候,里面还要加一个小括号是不是就清晰很多了!

eval()函数只能接受JS代码作为参数,而不能接受JSON格式字符串作为参数

因此,当你将一个JSON格式的字符串传递给eval()函数时,它会抛出语法错误

eval()函数不是你想传递一个字符串就一定能给你正确的进行解析成可执行的代码!

需要你去观察你传递的字符串信息是否合理合法, 这也很好的解释了w3c文档中提到的不是合法的表达式和语句传递给eval()函数是会报错的!

w3c文档上其实也有明确的规定, 在处理JSON字符串的时候,最好要写成以下方式:

代码如下

eval('('+jsondata+')');

这样写的目的是为了让代码更加清晰,更容易理解!

如图

举个栗子

我们假设一个JSON字符串数据如下:

var data ='{"username":"张三","age":"20","company":"阿里巴巴"}';
eval(data);

这里直接使用eval()函数解析这个JSON字符串显然不能直接解析成JSON对象, 因为刚刚上面我说过了,这里很明显把这个JSON字符串解析成了JS语句块,直接报错!

如图

那么我们可以给这个JSON字符串直接加上一个小括号()看看

代码如下

var data ='({"username":"张三","age":"20","company":"阿里巴巴"})';
var result=eval(data);
console.log(typeof result);
console.log(result);

如图

这里就是用了小括号()JS引擎把这一堆字符串当成一个整体来看待!

也就是我们在JSON字符串的两端添加括号,就可以将其转换为一个整体的JavaScript表达式

并将结果存储在变量中。现在这个变量是一个JS对象,我们可以使用它来访问JSON数据的属性了!

如果当你不加括号的时候的时候{}会被解释成一个复合语句块

所以你经常可能会见到在使用eval()函数解析JSON字符串的时候会写成eval('('+json+')');这个样子

扩展

其实也不用那么麻烦, 直接使用JSON.parse()函数就可以解决这个问题了,要解析JSON字符串直接就用这个,最方便!

var data ='{"username":"张三","age":"20","company":"阿里巴巴"}';
var result=JSON.parse(data);
console.log(typeof result);
console.log(result);

效果跟上面是一样的!

eval()函数应用场景

我们可能经常会在ajax提取后端数据的时候,会获取到一个json数据,那么可能这个json数据是一个字符串,

当你拿到之后不能直接使用, 如果直接使用eval()函数就会报错或者打印不出数据返回出undefined等等结果!

所以要再eval()函数里面加一个小括号

如图

"👍点赞" "✍️评论" "收藏❤️"

大家的支持就是我坚持下去的动力!

如果以上内容有任何错误或者不准确的地方,🤗🤗🤗欢迎在下面 👇👇👇 留个言指出、或者你有更好的想法,
欢迎一起交流学习❤️❤️💛💛💚💚

更多 好玩 好用 好看的干货教程可以 点击下方关注❤️ 微信公众号❤️
说不定有意料之外的收获哦..🤗嘿嘿嘿、嘻嘻嘻🤗!
🌽🍓🍎🍍🍉🍇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/638599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【redis-初级】

文章目录 1.非关系型数据库(NoSQL)2.在Linux上安装redis2.1 安装前准备2.2 安装2.3 启动2.4 关闭 3. redis客户端3.1 命令客户端3.2redis远程客户端3.3 redis编程客户端 1.非关系型数据库(NoSQL) 2.在Linux上安装redis 2.1 安装前…

抑郁症评估干预系统开发 还你美好人生

随着时代的发展,生活压力越来越大,抑郁症似乎也成为了很常见的心理健康问题,让很多家庭苦不堪言,轻者痛苦折磨,重者甚至会出现自虐自杀,所以人们也越来越重视心理健康问题,想要摆脱抑郁症的束缚…

HP DA1023电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网,转载需注明出处。(下载请直接百度黑果魏叔) 硬件配置 硬件型号驱动情况 主板HP DA1023 处理器Intel(R) Core(TM) i5-8265U已驱动 内存8 GB 2400 MHz DDR4.已驱动 硬盘Samsung SSD 980 250GB(macOS)已驱动 显卡I…

从零开始 Spring Boot 37:初始化 ApplicationContext

从零开始 Spring Boot 37:初始化 ApplicationContext 图源:简书 (jianshu.com) 从前文可以知道,作为 Ioc 容器的 ApplicationContext,需要进行一系列步骤来初始化以最终就绪(对于 Web 应用来说就是可以提供Http服务&a…

[PyTorch][chapter 39][nn.Module]

前言: pytorch.nn是专门为神经网络设计的模块化接口. nn构建于autograd之上,可以用来定义和运行神经网络.是所有类的父类. 目录: 基本结构 常用模块 container(容器) CPU,GPU 部署 train-test 环境切换 flatten MyLinear 一…

【kali】设置系统方式为中文

目录 1、右击终端 2、输入命令回车 3、需要输入当前账户密码 4、选择语言 5、再次确定 6、输入命令重启 1、右击终端 2、输入命令回车 sudo dpkg-reconfigure locales 3、需要输入当前账户密码 4、选择语言 依次选中en_US.UTF-8 / zh_CN.GBK(没找到&#xf…

野火启明RenesasRA4M2 UDS诊断bootloader 升级MCU

基于can总线的UDS软件升级 最近学习UDS诊断协议(ISO14229),是一项国际标准,为汽车电子系统中的诊断通信定义了统一的协议和服务。它规定了与诊断相关的服务需求,并没有设计通信机制。ISO14229仅对应用层和会话层做出了…

微信一天可以加多少个好友?

微信作为最大的私域流量池,几乎所有的人都会往微信引流,而微信每天加好友数量是有严格限制的。微信每天加多少人不会封号?微信每天加多少好友才不会被限制?微信频繁加好友被限制怎么办?请跟随小编的脚步一起往下看吧。…

IP地址定位原理

IP地址定位是一种通过IP地址来确定位置的技术,在互联网和移动网络的应用十分广泛。本文将介绍IP地址定位的原理和实现方式。 IP地址定位原理 IP地址是Internet Protocol(简称IP)的缩写,是互联网上的一个地址标识符用于识别连接到…

合成化学物:169219-08-3,Fmoc-Thr(Ac4Manα)-OH,一种甘露糖苏氨酸

Fmoc-Thr(Ac4Manα)-OH,甘露糖苏氨酸,供应商:陕西新研博美生物科技有限公司产品结构式: 产品规格: 1.CAS号:169219-08-3 2.分子式:C33H37NO14 3.分子量:671.65 4.包装规格&#xff1…

K8s in Action 阅读笔记——【14】Securing cluster nodes and the network

K8s in Action 阅读笔记——【14】Securing cluster nodes and the network 迄今为止,创建了 Pod 而不考虑它们允许消耗多少 CPU 和内存。但是,正如将在本章中看到的那样,设置 Pod 预期消耗和允许消耗的最大数量是任何 Pod 定义的重要部分。…

如何进行JMeter分布式压测?一个案例教你详细解读!

目录 引言 一、什么是压力测试? 二、什么是分布式测试? 三、为什么要使用分布式压力测试? 四、主流压力测试工具对比 五、Jmeter分布式压测原理 六、Jmeter分布式压测前的准备工作 七、阿里云服务器上进行分布式压测 八、系统架构学…

ATTCK v13版本战术介绍——凭证访问(二)

一、引言 在前几期文章中我们介绍了ATT&CK中侦察、资源开发、初始访问、执行、持久化、提权、防御规避战术,本期我们为大家介绍ATT&CK 14项战术中凭证访问战术第7-12种子技术,后续会介绍凭证访问其他子技术,敬请关注。 二、ATT&…

这两个小众的资源搜索工具其实很好用

01 小不点搜索是一个中国网络技术公司开发的网盘搜索引擎,该网站通过与多个主流网盘进行整合,为用户提供一种快速查找和下载文件的方式。小不点搜索因其高效性、便利性和实用性受到了广大用户的喜爱。 在技术实现上,小不点搜索拥有先进的搜…

C++项目打包成可调用dll文件python调用

目录 1.原项目如图 2.直接在项目对应地方新增dll.h,dll.cpp 3.改变工程的配置类型---动态库(.dll) 4.生成解决方案----可调用dll文件 5.查找dll依赖的其他dll 6.python调用dll 7.python调用dll打包成exe 相关dll要放一个文件夹 1.原项目如图 包括头文件uiaccess.h&#xff0…

Linux中Crontab(定时任务)命令详解及使用教程

Crontab介绍:Linux crontab是用来crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。该词来源于希腊语 chronos(χρ?…

【云计算】Ubuntu多种安装docker方式

文章目录 前言一、docker官网二、安装docker1、第一种方式(官方)2、使用脚本安装(阿里云):3、使用官方脚本安装:拉取镜像(solo博客部署) 前言 Docker是一款开源的容器化平台&#x…

Misc(4)

RAR 打开是个加密压缩文件,给了提示说是4位纯数字加密 暴力破解为4位数字,获得flag QR 下载下来是一个二维码 很简单,利用工具一下就解出来了 镜子里的世界 打开后是一张图片,根据题目的提示,猜想可能是镜像翻转后得到…

java springboot整合MyBatis做数据库查询操作

首先 我们还是要搞清楚 MyBatis 工作中都需要那些东西 首先是基础配置 你要连哪里的数据 连什么类型的数据库 以什么权限去连 然后 以 注解还是xml方式去映射sql 好 我们直接上代码 我们先创建一个文件夹 然后打开idea 新建一个项目 然后 按我下图的操作配置一下 然后点下一…

小米秋招笔试题(强化基础)

1、已知const arr [A, B, C, D, E, F, G],下面可以获取数组最后一项的表达式有 A arr[6] B arr.pop() C arr.shift() D arr.unshift() 答案: AB 解析: shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。…