浅入浅出JS中的eval及json
声明:
首先声明一下,本人是JS新手,所以不敢说深入,只是把最近对eval的学习经验拿出来跟大家分享,如果您是高手可略去不看。
适合读者:
对JS中的eval一知半解,不知eval是如何把字符串转换为json对象的,在用eval把字符串转换为json时常遇到“missing ] after element list”错误却不知哪儿错了的朋友
一、Eval介绍(这部分来自http://www.w3school.com.cn/js/jsref_eval.asp)
定义和用法:eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
语法:eval(string)
参数string:必需。要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句。
返回值:通过计算 string 得到的值(如果有的话)。
说明:该方法只接受原始字符串作为参数,如果 string 参数不是原始字符串,那么该方法将不作任何改变地返回。因此请不要为 eval() 函数传递 String 对象来作为参数。如果试图覆盖 eval 属性或把 eval() 方法赋予另一个属性,并通过该属性调用它,则 ECMAScript 实现允许抛出一个 EvalError 异常。
异常:如果参数中没有合法的表达式和语句,则抛出 SyntaxError 异常。如果非法调用 eval(),则抛出 EvalError 异常。如果传递给 eval() 的 Javascript 代码生成了一个异常,eval() 将把该异常传递给调用者。
二、Eval用法示例
对于编程方面的问题我一直认为说明问题最好的方法就是示例,看了上面的定义我们再来看几个例子:
code 1:
1 var code1="\"a\" + 2";
2 var code2= {"a":2};
3 var code3 ="{\"b\":3}";
4
5 console.log(code1);
6 console.log(eval(code1));
7
8 console.log(code2);
9 console.log(code2.a);
10 console.log(eval(code2));
11 console.log(eval('('+ code2 +')'));
12
13 console.log(code3);
14 console.log(code3.b);
15 t = eval('('+code3+')');
16 console.log(t);
17 console.log(t.b);
从5到17行分别会输出什么呢?在这里简单解析一下:
code1是一个字符串加数字的表达式字符串,所以第5行原样输出为"a"+2,第6行经eval运算后输出a2。
code2是一个json对象(关于json定义参考:深入浅出JSON),所以第8行输出Object { a=2},如果用alert(code2)会弹出[object Object]。第9行输出2。第10行呢,由于code2是一个json对象,不是一个字符串,因此eval在这里没有起作用,原样返回,所以跟第8行输出一样。第11行呢,由于code2已经是一个json对象,把json对象两边加一个括号进行运算的结果是什么呢,JS中这个语法是错的,所以这行会报异常,如果我们捕获一下异常输出会是什么呢,就是新手非常头痛的“missing ] after element list”了。
code3是一个json格式的字符串,因此第13行输出{"b":3}。第14行输出undefined。第15行对这个字符串加括号(加括号的原因请看下文)后进行eval运算,把字符串转换成了json对象,所以第16行输出Object { b=3},第17行输出3。
是不是这样呢,看看结果吧:

三、Eval把json格式字符串转换为json对象为什么要加括号
这一点园子里有一篇文章讲得比较清楚(原文链接:eval和JSON),这里就不献丑了,这里直接用原文的话来说明。加上圆括号的目的是迫使eval函数在评估JavaScript代码的时候强制将括号内的表达式(expression)转化为对象,而不是作为语句(statement)来执行。举一个例子,例如对象字面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始和结束标记,那么{}将会被认为是执行了一句空语句。所以下面两个执行结果是不同的:
code 2:
1 alert(eval("{}"); // return undefined
2 alert(eval("({})");// return object[Object]
所以,code 1中第15行要加上括号,如果不加会怎么样呢,大家可以测试一下。关于这一点,大家可以类比一下SQL语句,当一个子查询结果要做为关联表用时,会在查询语句两边加上括号,如:
code 3:
selecttop10*from TB where ID notin (selecttop5 ID from TB)
四、jquery中ajax返回值的处理
用eval把字符串转换为json对象用的最多的地方就是在ajax中。ajax的返回值有些是json格式的字符串,所以要用eval('('+返回的json格式字符串+')')来转换,这样写一般是没有问题的,但现在有很多是用jquery中的ajax方法来做的,jquery的强大也让很多人在用时容易忽略一些问题,比较常见的就是contentType跟dataType,contentType与本文没什么关系,这里只说说dataType参数。
dataType可用的类型有xml,html,script,json,jsonp,text,用的比较多的是xml,json,text。有些朋友在用时不管dataType是什么类型,都把返回值eval一下,有时碰巧对了,有时错了就不知道问题出在哪儿,一筹莫展。
dataType是预期服务器返回的数据类型,如果不指定jQuery将自动根据HTTP包MIME信息返回responseXML或responseText。也就是说如果你dataType写的是json格式,jQuery在返回时已经把返回值转换成了json对象,这时就不需要再用eval转换了,如果dataType写的是text才需要用eval转换。
转载自:artwl http://www.cnblogs.com/artwl/archive/2011/09/07/2169680.html
浅入浅出JS中的eval及json的更多相关文章
- 包学会之浅入浅出Vue.js:结业篇(转)
蔡述雄,现腾讯用户体验设计部QQ空间高级UI工程师.智图图片优化系统首席工程师,曾参与<众妙之门>书籍的翻译工作.目前专注前端图片优化与新技术的探研. 在第一篇<包学会之浅入浅出Vu ...
- 包学会之浅入浅出Vue.js:升学篇
包学会之浅入浅出Vue.js:升学篇 蔡述雄,现腾讯用户体验设计部QQ空间高级UI工程师.智图图片优化系统首席工程师,曾参与<众妙之门>书籍的翻译工作.目前专注前端图片优化与新技术的探研. ...
- 包学会之浅入浅出Vue.js:开学篇(转)
包学会之浅入浅出Vue.js:开学篇 蔡述雄,现腾讯用户体验设计部QQ空间高级UI工程师.智图图片优化系统首席工程师,曾参与<众妙之门>书籍的翻译工作.目前专注前端图片优化与新技术的探研. ...
- 包学会之浅入浅出Vue.js:结业篇
在第一篇<包学会之浅入浅出Vue.js:开学篇>和上一篇<包学会之浅入浅出Vue.js:升学篇>的学习中,我们首先了解了Vue环境的搭建以及两个重要思想——路由和组件的学习,通 ...
- 浅入深出之Java集合框架(中)
Java中的集合框架(中) 由于Java中的集合框架的内容比较多,在这里分为三个部分介绍Java的集合框架,内容是从浅到深,如果已经有java基础的小伙伴可以直接跳到<浅入深出之Java集合框架 ...
- 『浅入深出』MySQL 中事务的实现
在关系型数据库中,事务的重要性不言而喻,只要对数据库稍有了解的人都知道事务具有 ACID 四个基本属性,而我们不知道的可能就是数据库是如何实现这四个属性的:在这篇文章中,我们将对事务的实现进行分析,尝 ...
- 浅入浅出---JQuery究竟是什么?
学习完了JQuery之后.我便感觉云里雾里的,JQuery究竟是什么.朦朦胧胧感觉到JQuery应该是javascript函数的封装.就应该像WinForm窗口应用程序中能够调用的系统函数,据之前所学 ...
- 浅入深出Vue:第一个页面
今天正式开始入门篇,也就是实战了~ 首先我们是要做一个博客网站,UI 框架采用江湖传闻中的 ElementUI,今天我们就来利用它确定我们博客网站的基本布局吧. 准备工作 新建一个vue项目(可以参考 ...
- 浅入深出Vue:代码整洁之封装
深入浅出vue系列文章已经更新过半了,在入门篇中我们实践了一个小小的项目. <代码整洁之道>一书中提到过一句话: 神在细节中 这句话来自20世纪中期注明现代建筑大师 路德维希·密斯·范·德 ...
随机推荐
- mysql八:视图、触发器、事务、存储过程、函数
一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...
- http_build_query
http_build_query (PHP 5) http_build_query -- 生成 url-encoded 之后的请求字符串描述string http_build_query ( arra ...
- Redis经验谈(转)
原文:http://www.programmer.com.cn/14577/ 新浪作为全世界最大的Redis用户,在开发和运维方面有非常多的经验.本文作者来自新浪,希望能为业界提供一些亲身经历,让大家 ...
- tomcat访问
1:html页面或者需要访问的对象需要放置到webapps/ROOT下面既可以 http://localhost:8080/直接访问 2:
- [py]监控内存并出图
监控内存出图 先将内存数据搞到数据库 已使用内存算法 used = int(total) - int(free) - int(butffers) - int(cache) pymysql模块使用 db ...
- mysql 用户授权命令
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your_root_password' WITH GRANT OP ...
- testng入门教程3用TestNG执行case的顺序
本教程介绍了TestNG中执行程序的方法,这意味着该方法被称为第一和一个接着.下面是执行程序的TestNG测试API的方法的例子. 创建一个Java类文件名TestngAnnotation.java在 ...
- 7.11 Models -- Customizing Adapters
一.概述 1. 在Ember Data中,和后台数据存储通信的逻辑存在于Adapter中.Ember Data的有一些内置的假设,一个 REST API 应该怎么看.如果你的后台约定和这些假设不同,E ...
- 软件包管理:rpm命令管理-包命名与依赖性
rpm包的管理主要有两种方法:一种是rpm命令管理另一种是yum在线管理 注意软件包没有扩展名,写上只是为了好看,便于识别而已. 注意区别包名,包全名.之所以要区分,就是因为有些命令十分挑剔,需要跟正 ...
- Django初级手册6-静态文件
用Django加载外部文件 在Django中iamges,JS或者CSS通称为static文件 定制APP的外观 一般放在应用目录下的static/polls/目录下,下为polls/static/p ...