javascript中eval解析JSON字符串


Posted in Javascript onFebruary 27, 2016

我们都知道,高级浏览器可以用  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

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

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

Javascript 相关文章推荐
最佳JS代码编写的14条技巧
Jan 09 Javascript
十个迅速提升JQuery性能让你的JQuery跑得更快
Dec 10 Javascript
对frameset、frame、iframe的js操作示例代码
Aug 16 Javascript
使用jquery.qrcode生成彩色二维码实例
Aug 08 Javascript
jQuery异步获取json数据方法汇总
Dec 22 Javascript
JS实现双击编辑可修改状态的方法
Aug 14 Javascript
javascript+HTML5 Canvas绘制转盘抽奖
May 16 Javascript
Bootstrap Metronic完全响应式管理模板之菜单栏学习笔记
Jul 08 Javascript
详解Javascript中的原型OOP
Oct 12 Javascript
详解Vue 开发模式下跨域问题
Jun 06 Javascript
AngularJS创建一个上传照片的指令实例代码
Feb 24 Javascript
vue 使用class创建和清除水印的示例代码
Dec 25 Vue.js
javascript先序遍历DOM树的方法
Feb 27 #Javascript
JavaScript开发者必备的10个Sublime Text插件
Feb 27 #Javascript
Javascript生成全局唯一标识符(GUID,UUID)的方法
Feb 27 #Javascript
JS原型、原型链深入理解
Feb 27 #Javascript
Javascript中Date类型和Math类型详解
Feb 27 #Javascript
原生javascript实现匀速运动动画效果
Feb 26 #Javascript
探索angularjs+requirejs全面实现按需加载的套路
Feb 26 #Javascript
You might like
一条久听不愿放下的DIY森海MX500,三言两语话神奇
2021/03/02 无线电
php二维数组排序与默认自然排序的方法介绍
2013/04/27 PHP
PHP的基本常识小结
2013/07/05 PHP
php截取字符串函数substr,iconv_substr,mb_substr示例以及优劣分析
2014/06/10 PHP
ThinkPHP登录功能的实现方法
2014/08/20 PHP
php动态生成缩略图并输出显示的方法
2015/04/20 PHP
PHP实现递归复制整个文件夹的类实例
2015/08/03 PHP
浅谈PHP发送HTTP请求的几种方式
2017/07/25 PHP
php实现QQ小程序发送模板消息功能
2019/09/18 PHP
PHP Web表单生成器案例分析
2020/06/02 PHP
JQuery EasyUI 对话框的使用方法
2010/10/24 Javascript
jquery库或JS文件在eclipse下报错问题解决方法
2014/04/17 Javascript
JavaScript实现简单Tip提示框效果
2016/04/20 Javascript
AngularJS入门教程之控制器详解
2016/07/27 Javascript
使用Ajax与服务器(JSON)通信实例
2016/11/04 Javascript
javaScript基础详解
2017/01/19 Javascript
提高JavaScript执行效率的23个实用技巧
2017/03/01 Javascript
layui实现文件或图片上传记录
2018/08/28 Javascript
vue中tab选项卡的实现思路
2018/11/25 Javascript
vue封装一个简单的div框选时间的组件的方法
2019/01/06 Javascript
node后端服务保活的实现
2019/11/10 Javascript
微信小程序学习总结(三)条件、模板、文件引用实例分析
2020/06/04 Javascript
原生js滑动轮播封装
2020/07/31 Javascript
Python下singleton模式的实现方法
2014/07/16 Python
Python实现模拟时钟代码推荐
2015/11/08 Python
python实现两个文件合并功能
2018/04/01 Python
python scp 批量同步文件的实现方法
2019/01/03 Python
python 将大文件切分为多个小文件的实例
2019/01/14 Python
django中related_name的用法说明
2020/05/20 Python
Anaconda详细安装步骤图文教程
2020/11/12 Python
实习生自荐信范文分享
2013/11/27 职场文书
护理专科毕业生自荐书范文
2014/02/19 职场文书
生物技术专业求职信
2014/06/10 职场文书
个人股份转让协议书范本
2015/01/28 职场文书
各类场合主持词开场白范文集锦
2019/08/16 职场文书
Spring mvc是如何实现与数据库的前后端的连接操作的?
2021/06/30 Java/Android