之前写过一篇 关于 JSON 的介绍文章,里面谈到了 JSON 的解析。我们都知道,高级浏览器可以用 JSON.parse() API 将一个 JSON 字符串解析成 JSON 数据,稍微欠妥点的做法,我们可以用eval() 函数。

var str = '{"name": "hanzichi", "age": 10}';
var obj = eval('(' + str + ')');
console.log(obj); // Object {name: "hanzichi", age: 10}

是否注意到,向 eval() 传参时,str 变量外裹了一层小括号?为什么要这样做?

我们先来看看 eval 函数的定义以及使用。

eval() 的参数是一个字符串。如果字符串表示了一个表达式,eval() 会对表达式求值。如果参数表示了一个或多个 JavaScript 声明, 那么 eval() 会执行声明。不要调用 eval() 来为算数表达式求值; JavaScript 会自动为算数表达式求值。

简单地说,eval 函数的参数是一个字符串,如果把字符串 "noString" 化处理,那么得到的将是正常的可以运行的 JavaScript 语句。

怎么说?举个栗子,如下代码:

var str = "alert('hello world')";
eval(str);

执行后弹出 "hello world"。我们把 str 变量 "noString" 化,粗暴点的做法就是去掉外面的引号,内部调整(转义等),然后就变成了:

alert('hello world')

very good!这是正常的可以运行的 JavaScript 语句!运行之!

再回到开始的问题,为什么 JSON 字符串要裹上小括号。如果不加,是这个样子的:

var str = '{"name": "hanzichi", "age": 10}';
var obj = eval(str);  // Uncaught SyntaxError: Unexpected token :

恩,报错了。为什么会报错?试试把 str "noString" 化,执行一下:

{"name": "hanzichi", "age": 10};  // Uncaught SyntaxError: Unexpected token :

毫无疑问,一个 JSON 对象或者说是一个对象根本就不是能执行的 JavaScript 语句!等等,试试以下代码:

var str = '{name: "hanzichi"}';
var obj = eval(str);
console.log(obj); // hanzichi

这又是什么鬼?但是给 name 加上 "" 又报错?

var str = '{"name": "hanzichi"}';
var obj = eval(str);  // Uncaught SyntaxError: Unexpected token :
console.log(obj); 

好吧,快晕了,其实还是可以将 str "nostring" 化,看看是不是能正确执行的 JavaScript 语句。前者的结果是:

{name: "hanzichi"}

这确实是一条合法的 JavaScript 语句。{} 我们不仅能在 if、for 语句等场景使用,甚至可以在任何时候,因为 ES6 之前 JavaScript 只有块级作用域,所以对于作用域什么的并不会有什么冲突。去掉 {} 后 name: "hanzichi" 也是合法的语句,一个 label 语句,label 语句在跳出嵌套的循环中非常好用,具体可以参考 label,而作为 label 语句的标记,name 是不能带引号的,标记能放在 JavaScript 代码的任何位置,用不到也没关系。

一旦一个对象有了两个 key,比如 {name: "hanzichi", age: 10},ok,两个 label 语句?将 "hanzhichi" 以及 10 分别看做是语句,但是 语句之间只能用封号连接!(表达式之间才能用逗号)。所以改成下面这样也是没有问题的:

var str = '{name: "hanzichi"; age: 10}';
var obj = eval(str);
console.log(obj); // 10

越扯越远,文章开头代码的错误的原因是找到了,为什么套个括号就能解决呢?简单来说,() 会把语句转换成表达式,称为语句表达式。括号里的代码都会被转换为表达式求值并且返回,对象字面量必须作为表达式而存在

本文并不会大谈表达式,关于表达式,可以参考文末链接。值得记住的一点是,表达式永远有一个返回值。大部分表达式会包裹在() 内,小括号内不能为空,如果有多个表达式,用逗号隔开,也就是所谓的逗号表达式,会返回最后一个的值。

说到表达式,不得不提函数表达式,以前翻译过一篇关于立即执行函数表达式的文章,可以参考下,文末。

Read More:

eval解析JSON字符串的一个小问题的更多相关文章

  1. JS的全局函数eval解析JSON字符串

    JavaScript eval() 函数 定义和用法 eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码. 语法 eval(string) 参数 描述 string 必需. ...

  2. eval解析json字符串

    场景:在springMVC,手动拼接的list,转成本json字符串后,传到前台, 解决:需要解析成json对象,获取对象的属性,动态生成table. 首先,以下是后台准备好的list,list中有两 ...

  3. 为什么使用eval()将json字符串转换为对象要多加一个小括号

    使用eval()将json字符串转换为对象要多加一个小括号: 关于eval()函数的具体用法这里就不多介绍了,具体可以参阅javascript的eval()方法一章节,下面就介绍一下为什么使用eval ...

  4. JSON.stringify()方法是将一个javascript值(对象或者数组)转换成为一个JSON字符串;JSON.parse()解析JSON字符串,构造由字符串描述的javascript值或对象

    JSON.stringify()方法是将一个javascript值(对象或者数组)转换成为一个JSON字符串:JSON.parse()解析JSON字符串,构造由字符串描述的javascript值或对象

  5. js中eval详解,用Js的eval解析JSON中的注意点

    先来说eval的用法,内容比较简单,熟悉的可以跳过eval函数接收一个参数s,如果s不是字符串,则直接返回s.否则执行s语句.如果s语句执行结果是一个值,则返回此值,否则返回undefined. 需要 ...

  6. jquery : eval() 解析json的注意

    jquery eval解析JSON中的注意点介绍 来在:http://www.jb51.net/article/40842.htm 在JS中将JSON的字符串解析成JSON数据格式,一般有两种方式: ...

  7. java后台处理解析json字符串的两种方式

    简单说一下背景 上次后端通过模拟http请求百度地图接口,得到的是一个json字符串,而我只需要其中的某个key对应的value. 当时我是通过截取字符串取的,后来觉得不太合理,今天整理出了两种处理解 ...

  8. 使用 dynamic 标记解析JSON字符串 JDynamic :支持Json反序列化为Dynamic对象

    使用 dynamic 标记解析JSON字符串  http://www.cnblogs.com/taotaodetuer/p/4171327.html 1 string jsonStr = " ...

  9. C#解析JSON字符串总结

    JSON文件读取到内存中就是字符串,.NET操作JSON就是生成与解析JSON字符串. 操作JSON通常有以下几种方式: 1. 原始方式:按照JSON字符串自己来解析. 2. 通用方式[★★★★★]: ...

随机推荐

  1. 【转发】网易邮箱前端技术分享之javascript编码规范

    网易邮箱前端技术分享之javascript编码规范 发布日期:2013-11-26 10:06 来源:网易邮箱前端技术中心 作者:网易邮箱 点击:533 网易邮箱是国内最早使用ajax技术的邮箱.早在 ...

  2. Sql Server之旅——第五站 确实不得不说的DBCC命令(文后附年会福利)

    今天研发中心办年会,晚上就是各自部门聚餐了,我个人喜欢喝干红,在干红中你可以体味到那种酸甜苦辣...人生何尝不是这样呢???正好 ceo从美国带了干红回来,然后我就顺道开心的过了把瘾....一个字.. ...

  3. Spring 整体架构

    1. Core Container:核心容器(core.Beans.Context.Expression Language   Core.Beans框架基础构成,提供IOC.依赖注入特性.BeanFa ...

  4. 【hadoop】——修改hadoop FileUtil.java,解决权限检查的问题

    在Hadoop Eclipse开发环境搭建这篇文章中,第15.)中提到权限相关的异常,如下: 15/01/30 10:08:17 WARN util.NativeCodeLoader: Unable ...

  5. date

    更改时区 用系统备好的时区文件覆盖掉当前的配置文件,/etc/里装的是当前系统的配置文件 $sudo cp /usr/share/zoneinfo/Asia/Chongqing /etc/localt ...

  6. x01.Lab.OpenCV: 计算机视觉

    横看成岭侧成峰,计算视觉大不同.观看的角度不同,成像自然不同,这对计算机视觉来说,是个大麻烦.但计算机视觉应用如此广泛,却又有不得不研究的理由.指纹机大家都用过吧,这不过是冰山之一角.产品检测,机器人 ...

  7. android Bitmap类方法属性 详细说明

    (转:http://blog.csdn.net/ymangu666/article/details/37729109) 1.  BitMap类public void recycle()——回收位图占用 ...

  8. UVALive 5061 Lightning Energy Report --LCA

    题意:给一棵树,每次给u到v的路径上所有点加上一个值,最后输出每个点的权值(初始为0) 解法:每次在u,v间加k时,只要让u,v点的权值加上k,u,v的LCA处减去k(因为LCA的子树中加了两个k), ...

  9. 《深入.NET平台和C# 编程》内部测试 笔试题

    1:在C#中,关于文件操作相关的类说法正确的是(AB) <选择二项> A:FileInfo类提供了用于操作文件的实例方法 B:File类提供了用于操作文件的静态方法 C:Directory ...

  10. 查找代码错误.java

    class Other{ public int i; } class Something{ public static oivd main(String[]args){ Other o = new O ...