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 相关文章推荐
javascript生成/解析dom的CDATA类型的字段的代码
Apr 22 Javascript
jquery中dom操作和事件的实例学习 下拉框应用
Dec 01 Javascript
JS 精确统计网站访问量的实例代码
Jul 05 Javascript
JS实现模仿微博发布效果实例代码
Dec 16 Javascript
JavaScript三元运算符的多种使用技巧
Apr 16 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
Aug 23 Javascript
vue项目中的webpack-dev-sever配置方法
Dec 14 Javascript
vue一个页面实现音乐播放器的示例
Feb 06 Javascript
微信小程序通过保存图片分享到朋友圈功能
May 24 Javascript
vue 中 elment-ui table合并上下两行相同数据单元格
Dec 26 Javascript
微信小程序动态添加和删除组件的现实
Feb 28 Javascript
Openlayers实现图形绘制
Sep 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实例分享之二维数组排序
2014/05/15 PHP
使用Huagepage和PGO来提升PHP7的执行性能
2015/11/30 PHP
总结PHP中DateTime的常用方法
2016/08/11 PHP
利用PHP扩展Xhprof分析项目性能实践教程
2018/09/05 PHP
PHP面向对象程序设计之对象克隆clone和魔术方法__clone()用法分析
2019/06/12 PHP
一个js实现的所谓的滑动门
2007/05/23 Javascript
mysql输出数据赋给js变量报unterminated string literal错误原因
2010/05/22 Javascript
JS字符串函数扩展代码
2011/09/13 Javascript
使用jQuery动态加载js脚本文件的方法
2014/04/03 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
2014/05/01 Javascript
angular简介和其特点介绍
2015/01/29 Javascript
js实现固定宽高滑动轮播图效果
2017/01/13 Javascript
原生JS实现简单放大镜效果
2017/02/08 Javascript
Vue头像处理方案小结
2018/07/26 Javascript
微信小程序 slot踩坑的解决
2019/04/01 Javascript
vue指令之表单控件绑定v-model v-model与v-bind结合使用
2019/04/17 Javascript
Nodejs + Websocket 指定发送及群聊的实现
2020/01/09 NodeJs
python高并发异步服务器核心库forkcore使用方法
2013/11/26 Python
Python利用带权重随机数解决抽奖和游戏爆装备问题
2016/06/16 Python
Python 单元测试(unittest)的使用小结
2018/11/14 Python
对python字典过滤条件的实例详解
2019/01/22 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
django从后台返回html代码的实例
2020/03/11 Python
洛杉矶生活休闲而精致的基础品牌:Mika Jaymes
2018/01/07 全球购物
Bata印度官网:源自欧洲舒适鞋履品牌
2020/01/30 全球购物
上课迟到检讨书
2014/01/19 职场文书
大学生家政服务项目创业计划书
2014/01/30 职场文书
主持词开场白
2014/03/17 职场文书
新教师岗前培训方案
2014/06/05 职场文书
局领导领导班子四风对照检查材料
2014/09/27 职场文书
入党积极分子对十八届四中全会期盼的思想汇报
2014/10/17 职场文书
2015应届毕业生自荐信范文
2015/03/05 职场文书
详解vue中v-for的key唯一性
2021/05/15 Vue.js
JavaScript分页组件使用方法详解
2021/07/26 Javascript
分享node.js实现简单登录注册的具体代码
2022/04/26 NodeJs
鸿蒙3.0体验感怎么样? 鸿蒙3.0系统评测向
2022/08/14 数码科技