JS中Eval解析JSON字符串的一个小问题


Posted in Javascript onFebruary 21, 2016

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

JSON (JavaScript Object Notation)一种简单的数据格式,比xml更轻巧。 JSON 是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON 数据不需要任何特殊的 API 或工具包。

JSON的规则很简单: 对象是一个无序的“‘名称/值'对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值' 对”之间使用“,”(逗号)分隔

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

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

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

以上所述是小编给大家介绍了JS中Eval解析JSON字符串的一个小问题,希望对大家有所帮助!

Javascript 相关文章推荐
js 内存释放问题
Apr 25 Javascript
jquery与js函数冲突的两种解决方法
Sep 09 Javascript
用jquery写的一个万年历(自写)
Jan 20 Javascript
js阻止默认事件与js阻止事件冒泡示例分享 js阻止冒泡事件
Jan 27 Javascript
jquery序列化表单以及回调函数的使用示例
Jul 02 Javascript
js实现兼容IE和FF的上下层的移动
May 04 Javascript
jquery左右全屏大尺寸多图滑动效果代码分享
Aug 28 Javascript
微信小程序 连续旋转动画(this.animation.rotate)详解
Apr 07 Javascript
JS ES6多行字符串与连接字符串的表示方法
Apr 26 Javascript
vue-cli开发时,关于ajax跨域的解决方法(推荐)
Feb 03 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
Jul 27 Javascript
微信小程序实现简单评论功能
Nov 28 Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
Feb 21 #Javascript
gameboy网页闯关游戏(riddle webgame)--仿微信聊天的前端页面设计和难点
Feb 21 #Javascript
全面详细的jQuery常见开发技巧手册
Feb 21 #Javascript
完善的jquery处理机制
Feb 21 #Javascript
jquery对象和DOM对象的任意相互转换
Feb 21 #Javascript
jQuery实现div拖拽效果实例分析
Feb 20 #Javascript
jQuery实现简单隔行变色的方法
Feb 20 #Javascript
You might like
用PHP中的 == 运算符进行字符串比较
2006/11/26 PHP
解决phpcms更换javascript的幻灯片代码调用图片问题
2014/12/26 PHP
使用apply方法处理数组的三个技巧[译]
2012/09/20 Javascript
jquery scrollTop方法根据滚动像素显示隐藏顶部导航条
2013/05/27 Javascript
如何使用Jquery获取Form表单中被选中的radio值
2013/08/09 Javascript
javascript jq 弹出层实例
2013/08/25 Javascript
深入理解JavaScript高级之词法作用域和作用域链
2013/12/10 Javascript
JS调用页面表格导出excel示例代码
2014/03/18 Javascript
jQuery实现的向下图文信息滚动效果
2015/05/03 Javascript
JavaScript实现网页加载进度条代码超简单
2015/09/21 Javascript
JavaScript高级程序设计(第三版)学习笔记6、7章
2016/03/11 Javascript
JS中多步骤多分步的StepJump组件实例详解
2016/04/01 Javascript
最棒的Angular2表格控件
2016/08/10 Javascript
vue之封装多个组件调用同一接口的案例
2020/08/11 Javascript
win7安装python生成随机数代码分享
2013/12/27 Python
在ubuntu16.04中将python3设置为默认的命令写法
2018/10/31 Python
python找出完数的方法
2018/11/12 Python
Django如何自定义model创建数据库索引的顺序
2019/06/20 Python
python Gunicorn服务器使用方法详解
2019/07/22 Python
Python 脚本的三种执行方式小结
2019/12/21 Python
Python3读写Excel文件(使用xlrd,xlsxwriter,openpyxl3种方式读写实例与优劣)
2020/02/13 Python
python实现简单井字棋小游戏
2020/03/05 Python
django的autoreload机制实现
2020/06/03 Python
python之pygame模块实现飞机大战完整代码
2020/11/29 Python
英国No.1文具和办公用品在线:Euroffice
2016/09/21 全球购物
UNDONE手表官网:世界领先的定制手表品牌
2018/11/13 全球购物
Nike香港官网:Nike HK
2019/03/23 全球购物
法国春天百货官网:Printemps.com
2020/06/29 全球购物
.NET程序员的数据库面试题
2012/10/10 面试题
营销与策划应届生求职信
2013/11/04 职场文书
庆六一开幕词
2015/01/29 职场文书
诚信高考倡议书
2019/06/24 职场文书
浅谈Mysql多表连接查询的执行细节
2021/04/24 MySQL
React如何创建组件
2021/06/27 Javascript
MySQL 用 limit 为什么会影响性能
2021/09/15 MySQL
Apache Hudi的多版本清理服务彻底讲解
2022/03/31 Servers