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

🚀 个人主页 极客小俊
✍🏻 作者简介: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()函数里面加一个小括号

如图

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

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

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


关注 极客小俊 微信公众号 不定期更新免费技术干货



VX技术交流

posted @ 2023-07-11 11:11  极客小俊  阅读(9)  评论(0编辑  收藏  举报