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函数
Sep 08 Javascript
一个基于jquery的文本框记数器
Sep 19 Javascript
jquery中常用的SET和GET$(”#msg”).html循环介绍
Oct 09 Javascript
js读写cookie实现一个底部广告浮层效果的两种方法
Dec 29 Javascript
js select实现省市区联动选择
Apr 17 Javascript
微信小程序开发一键登录 获取session_key和openid实例
Nov 23 Javascript
原生js的ajax和解决跨域的jsonp(实例讲解)
Oct 16 Javascript
Vue响应式原理深入解析及注意事项
Dec 11 Javascript
详解vue-admin和后端(flask)分离结合的例子
Feb 12 Javascript
详解Chart.js轻量级图表库的使用经验
May 22 Javascript
微信小程序仿今日头条导航栏滚动解析
Aug 20 Javascript
vue 解决form表单提交但不跳转页面的问题
Oct 30 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 simple_html_dom.php+正则 采集文章代码
2009/12/24 PHP
PHP实现基于回溯法求解迷宫问题的方法详解
2017/08/17 PHP
php ajax confirm 删除实例详解
2019/03/06 PHP
js中判断文本框是否为空的两种方法
2011/07/31 Javascript
javascript的document.referrer浏览器支持、失效情况总结
2014/07/18 Javascript
前端轻量级MVC框架CanJS详解
2014/09/26 Javascript
jQuery遍历页面所有CheckBox查看是否被选中的方法
2015/04/14 Javascript
Javascript中For In语句用法实例
2015/05/14 Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(一)
2016/02/16 Javascript
BootStrap中的表单大全
2016/09/07 Javascript
jQuery与js实现颜色渐变的方法
2016/12/30 Javascript
jquery插件treegrid树状表格的使用方法详解(.Net平台)
2017/01/03 Javascript
浅谈js-FCC算法Friendly Date Ranges(详解)
2017/04/10 Javascript
layui选项卡效果实现代码
2017/05/19 Javascript
浅谈vue-lazyload实现的详细过程
2017/08/22 Javascript
JS实现登录页密码的显示和隐藏功能
2017/12/06 Javascript
vue axios请求超时的正确处理方法
2018/04/02 Javascript
JS 封装父页面子页面交互接口的实例代码
2019/06/25 Javascript
vue实现一拉到底的滑动验证
2019/07/25 Javascript
天翼开放平台免费短信验证码接口使用实例
2013/12/18 Python
virtualenv实现多个版本Python共存
2017/08/21 Python
很酷的python表白工具 你喜欢我吗
2019/04/11 Python
Pandas之Dropna滤除缺失数据的实现方法
2019/06/25 Python
python交易记录整合交易类详解
2019/07/03 Python
django项目简单调取百度翻译接口的方法
2019/08/06 Python
python利用xlsxwriter模块 操作 Excel
2020/10/14 Python
详解HTML5 录音的踩坑之旅
2017/12/26 HTML / CSS
前后端结合实现amazeUI分页效果
2020/08/21 HTML / CSS
当当网官方旗舰店:中国图书销售夺金品牌
2018/04/02 全球购物
台湾时尚彩瞳专门店:imeime
2019/08/16 全球购物
事业单位公务员的职业生涯规划
2014/01/15 职场文书
西式结婚主持词
2014/03/14 职场文书
2015年度个人思想工作总结
2015/04/08 职场文书
文明医院的标语集锦!
2019/07/24 职场文书
建国70周年的心得体会(2篇)
2019/09/20 职场文书
pytorch常用数据类型所占字节数对照表一览
2021/05/17 Python