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+XML 省份和城市之间的联动实现代码
Oct 14 Javascript
使用原生javascript创建通用表单验证——更锋利的使用dom对象
Sep 13 Javascript
javascript处理表单示例(javascript提交表单)
Apr 28 Javascript
js实现进度条的方法
Feb 13 Javascript
JS+CSS实现鼠标滑过时动态翻滚的导航条效果
Sep 24 Javascript
两种方法解决javascript url post 特殊字符转义 + & #
Apr 13 Javascript
JavaScript和jquery获取父级元素、子级元素、兄弟元素的方法
Jun 05 Javascript
深入浅析Vue.js中 computed和methods不同机制
Mar 22 Javascript
vue-router的HTML5 History 模式设置
Sep 08 Javascript
Vue父子传递实例讲解
Feb 14 Javascript
JS async 函数的含义和用法实例总结
Apr 08 Javascript
Javascript原型链及instanceof原理详解
May 25 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
77A一级收信机修理记
2021/03/02 无线电
让PHP支持断点续传的源码
2010/05/16 PHP
php防盗链的常用方法小结
2010/07/02 PHP
php学习笔记之面向对象编程
2012/12/29 PHP
对PHP新手的一些建议(PHP学习经验总结)
2014/08/20 PHP
遍历echsop的region表形成缓存的程序实例代码
2016/11/01 PHP
thinkPHP框架整合tcpdf插件操作示例
2018/08/07 PHP
javascript 关闭IE6、IE7
2009/06/01 Javascript
一个简单的jQuery插件制作 学习过程及实例
2010/04/25 Javascript
需要做特殊处理的DOM元素属性的访问
2010/11/05 Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
2011/06/02 Javascript
使用闭包对setTimeout进行简单封装避免出错
2013/07/10 Javascript
学习JavaScript设计模式(继承)
2015/11/26 Javascript
js根据手机客户端浏览器类型,判断跳转官网/手机网站多个实例代码
2016/04/30 Javascript
详解AngularJS通过ocLazyLoad实现动态(懒)加载模块和依赖
2017/03/01 Javascript
react实现pure render时bind(this)隐患需注意!
2017/03/09 Javascript
vue-cli脚手架打包静态资源请求出错的原因与解决
2019/06/06 Javascript
JS JQuery获取data-*属性值方法解析
2020/09/01 jQuery
Python实现简单状态框架的方法
2015/03/19 Python
Python去除、替换字符串空格的处理方法
2018/04/01 Python
Python补齐字符串长度的实例
2018/11/15 Python
Django 路由控制的实现
2019/07/17 Python
python 字符串追加实例
2019/07/20 Python
Python Pandas对缺失值的处理方法
2019/09/27 Python
python图像处理模块Pillow的学习详解
2019/10/09 Python
Pytorch通过保存为ONNX模型转TensorRT5的实现
2020/05/25 Python
python 实现控制鼠标键盘
2020/11/27 Python
State Cashmere官网:半零售价可持续蒙古羊绒
2020/02/26 全球购物
在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern "C"
2014/08/09 面试题
创立科技Java面试题
2015/11/29 面试题
护理自我鉴定范文
2013/10/06 职场文书
三查三看党性分析材料
2014/02/18 职场文书
信息员培训方案
2014/06/12 职场文书
学习党代会心得体会
2014/09/05 职场文书
2015年工会工作总结
2015/03/30 职场文书
会计专业自荐信范文
2019/05/22 职场文书