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 相关文章推荐
JavaScript QueryString解析类代码
Jan 17 Javascript
JavaScript显示当前文档最后修改日期的方法
Mar 19 Javascript
jQuery实现的登录浮动框效果代码
Sep 26 Javascript
JS中静态页面实现微信分享功能
Feb 06 Javascript
Vue.js实战之组件之间的数据传递
Apr 01 Javascript
ES6新特性之模块Module用法详解
Apr 01 Javascript
解决vue项目打包后提示图片文件路径错误的问题
Jul 04 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
May 27 Javascript
js实现简单页面全屏
Sep 17 Javascript
TypeScript的安装、使用、自动编译的实现
Apr 10 Javascript
javascript 内存模型实例详解
Apr 18 Javascript
微信小程序学习总结(一)项目创建与目录结构分析
Jun 04 Javascript
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
yii实现级联下拉菜单的方法
2014/07/31 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
2018/05/23 PHP
PHP实现的XXTEA加密解密算法示例
2018/08/28 PHP
js post方式传递提交的实现代码
2010/05/31 Javascript
JavaScript实用技巧(一)
2010/08/16 Javascript
JQuery弹出层示例可自定义
2014/05/19 Javascript
JS面向对象(3)之Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
2016/02/25 Javascript
node.js实现爬虫教程
2020/08/25 Javascript
js实现页面跳转的几种方法小结
2016/05/16 Javascript
移动端点击态处理的三种实现方式
2017/01/12 Javascript
基于vue.js轮播组件vue-awesome-swiper实现轮播图
2017/03/17 Javascript
JS获取鼠标坐标并且根据鼠标位置不同弹出不同内容
2017/06/12 Javascript
bootstrap模态框关闭后清除模态框的数据方法
2018/08/10 Javascript
vue单文件组件lint error自动fix与styleLint报错自动fix详解
2019/01/08 Javascript
JS实现点击li标签弹出对应的索引功能【案例】
2019/02/18 Javascript
VUE安装使用教程详解
2019/06/03 Javascript
详解如何提升JSON.stringify()的性能
2019/06/12 Javascript
jquery 回调操作实例分析【回调成功与回调失败的情况】
2019/09/27 jQuery
Node.js path模块,获取文件后缀名操作
2020/11/07 Javascript
[01:28]国服启动器接入蒸汽平台操作流程视频
2021/03/11 DOTA
Python基于Matplotlib库简单绘制折线图的方法示例
2017/08/14 Python
解决Django模板无法使用perms变量问题的方法
2017/09/10 Python
基于python的多进程共享变量正确打开方式
2018/04/28 Python
浅谈numpy生成数组的零值问题
2018/11/12 Python
在Python中构建增广矩阵的实现方法
2019/07/01 Python
Python使用sys.exc_info()方法获取异常信息
2020/07/23 Python
Opencv python 图片生成视频的方法示例
2020/11/18 Python
基于CSS3实现立方体自转效果
2016/03/01 HTML / CSS
世界上最大的网络主机公司:1&1
2016/10/12 全球购物
个人简历中自我评价
2014/02/11 职场文书
大学生个人学习总结
2015/02/15 职场文书
起诉书格式范文
2015/05/20 职场文书
吴仁宝观后感
2015/06/09 职场文书
2016年学校党支部公开承诺书
2016/03/25 职场文书
golang 语言中错误处理机制
2021/08/30 Golang
MySql数据库触发器使用教程
2022/06/01 MySQL