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 相关文章推荐
brook javascript框架介绍
Oct 10 Javascript
使用CSS3的scale实现网页整体缩放
Mar 18 Javascript
javascript+canvas实现刮刮卡抽奖效果
Jul 29 Javascript
javascript实现倒计时跳转页面
Jan 17 Javascript
AngualrJS中的Directive制作一个菜单
Jan 26 Javascript
JS实现点击登录弹出窗口同时背景色渐变动画效果
Mar 25 Javascript
用jQuery的AJax实现异步访问、异步加载
Nov 02 Javascript
javascript 跨域问题以及解决办法
Jul 17 Javascript
解决JQuery全选/反选第二次失效的问题
Oct 11 jQuery
微信小程序实现的贪吃蛇游戏【附源码下载】
Jan 03 Javascript
node.js环境搭建图文详解
Sep 19 Javascript
uniapp实现可以左右滑动导航栏
Oct 21 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全角字符转换为半角函数
2014/02/07 PHP
Yii2增加验证码步骤详解
2016/04/25 PHP
php写app接口并返回json数据的实例(分享)
2017/05/20 PHP
PHP用continue跳过本次循环中剩余代码的注意点
2017/06/27 PHP
pjblog修改技巧汇总
2007/03/12 Javascript
为radio类型的INPUT添加客户端脚本(附加实现JS来禁用onClick事件思路代码)
2010/11/11 Javascript
JavaScript面向对象(极简主义法minimalist approach)
2012/07/17 Javascript
使用jQuery同时控制四张图片的伸缩实现代码
2013/04/19 Javascript
JavaScript Math.ceil() 函数使用介绍
2013/12/11 Javascript
判断某个字符在一个字符串中是否存在的js代码
2014/02/28 Javascript
JS中判断null、undefined与NaN的方法
2014/03/24 Javascript
JavaScript检查数字是否为整数或浮点数的方法
2015/06/09 Javascript
JQuery节点元素属性操作方法
2015/06/11 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
2015/08/06 Javascript
js实现改进的仿蓝色论坛导航菜单效果代码
2015/09/06 Javascript
JS+CSS实现六级网站导航主菜单效果
2015/09/28 Javascript
基于JS如何实现给字符加千分符(65,541,694,158)
2016/08/03 Javascript
微信小程序 scroll-view隐藏滚动条详解
2017/01/16 Javascript
详解打造 Vue.js 可复用组件
2017/03/24 Javascript
搭建element-ui的Vue前端工程操作实例
2018/02/23 Javascript
通过封装scroll.js 获取滚动条的值
2018/07/13 Javascript
浅谈Vue组件单元测试究竟测试什么
2020/02/05 Javascript
vue+vuex+axios从后台获取数据存入vuex,组件之间共享数据操作
2020/07/31 Javascript
在Python3中初学者应会的一些基本的提升效率的小技巧
2015/03/31 Python
python算法表示概念扫盲教程
2017/04/13 Python
用python3教你任意Html主内容提取功能
2018/11/05 Python
简单了解python的一些位运算技巧
2019/07/13 Python
python 实时调取摄像头的示例代码
2020/11/25 Python
利用HTML5实现使用按钮控制背景音乐开关
2015/09/21 HTML / CSS
HTML5录音实践总结(Preact)
2020/05/07 HTML / CSS
香蕉共和国工厂店:Banana Republic Factory
2018/06/09 全球购物
linux面试题参考答案(8)
2016/04/19 面试题
家长给幼儿园的表扬信
2014/01/09 职场文书
乡镇交通安全实施方案
2014/03/29 职场文书
白酒营销策划方案
2014/08/17 职场文书
交警作风整顿剖析材料
2014/10/11 职场文书