javascript中eval()函数使用方法

本教程主要重介绍eval()函数的语法与使用方法,及在后面我还补充了eval()解析json数据的相关例子,但愿文章能帮助到各位深刻理解eval()使用方法吧。
 

前几天说到js中尽可能不要使用eval,可是eval究竟是什么那?今天咱们就说说eval的那点事。
 php

首先看一下本定义:java

定义和用法jquery

eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。ajax

语法express

eval(string)json

 

参数浏览器

描述安全

 

string    必需。要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句。   服务器

返回值闭包

经过计算 string 获得的值(若是有的话)。

说明

该方法只接受原始字符串做为参数,若是 string 参数不是原始字符串,那么该方法将不做任何改变地返回。所以请不要为 eval() 函数传递 String 对象来做为参数。

若是试图覆盖 eval 属性或把 eval() 方法赋予另外一个属性,并经过该属性调用它,则 ECMAScript 实现容许抛出一个 EvalError 异常。

抛出

若是参数中没有合法的表达式和语句,则抛出 SyntaxError 异常。

若是非法调用 eval(),则抛出 EvalError 异常。

若是传递给 eval() 的 Javascript 代码生成了一个异常,eval() 将把该异常传递给调用者。

提示和注释

提示:虽然 eval() 的功能很是强大,但在实际使用中用到它的状况并很少。

 

实例代码:

eval函数接收一个参数s,若是s不是字符串,则直接返回s。不然执行s语句。若是s语句执行结果是一个值,则返回此值,不然返回undefined。 
须要特别注意的是对象声明语法“{}”并不能返回一个值,须要用括号括起来才会返回值,简单示例以下:

 代码以下 复制代码
var code1='"a" + 2'; //表达式
  
varcode2='{a:2}'; //语句
  
alert(eval(code1)); //->'a2'
  
alert(eval(code2)); //->undefined
  
alert(eval('(' + code2 + ')')); //->[object Object]

eval函数的特色,它老是在调用它的上下文变量空间(也称为:包,closure)内执行,不管是变量定义仍是函数定义都是如此


eval做用域

先看这段代码:

 代码以下 复制代码
var x = 1;
(function () {
    eval('var x = 123;');
})();
console.log(x);

这个代码获得的是 1 而不是 123
若是想让 eval 执行的代码是全局的,那么有几种方法。

 代码以下 复制代码
var x = 1;
(function () {
    window.eval('var x = 123;');
})();
console.log(x);

这个方法标准浏览器均可以获得 123 而IE6-8则依然是 1

相同的例如

 代码以下 复制代码

var arr = [0,0,0,0,0,0];
(function () {
    var arr = [1,1,1,1,1,1];
    var _eval = eval;
    window.eval('arr[0] = 123;');
    eval.call(null, 'arr[1] = 123;');
    _eval('arr[2] = 123;');
    (0,eval)('arr[3] = 123;');
})();
console.log(arr);

0,1 貌似不支持IE8- 2,3 貌似不支持 IE7-
反正归根结底就是兼容性有问题。

不过还在IE下有个 execScript 很是好使。

 代码以下 复制代码

var x = 1;
(function () {
    (!-[1,] ? execScript : eval)('var x = 123;');
})();
console.log(x);

eval不可能在全局空间内执行,这就给开发带来了很多问题,也看到过不少人为此郁闷。 
不过如今偶终于找到了解决办法,嘿嘿,能够同时兼容IE和Firefox,方法以下:

 代码以下 复制代码
var X2={} //my namespace:)
  
X2.Eval=function(code){
  
if(!!(window.attachEvent && !window.opera)){
  
//ie
  
execScript(code);
  
}else{
  
//not ie
  
window.eval(code);
  
}
  
}

如今若是要想在函数内定义全局代码,就能够经过调用X2.eval_r(code)方法。

 代码以下 复制代码

var s='global';
  
function demo3(){
  
X2.Eval('var s="local"');
  
}
  
demo3();
  
alert(s); //->'local'


eval解析json

代码以下:

 代码以下 复制代码
var data=" 

root: 

{name:'1',value:'0'}, 
{name:'6101',value:'北京市'}, 
{name:'6102',value:'天津市'}, 
{name:'6103',value:'上海市'}, 
{name:'6104',value:'重庆市'}, 
{name:'6105',value:'渭南市'}, 
{name:'6106',value:'延安市'}, 
{name:'6107',value:'汉中市'}, 
{name:'6108',value:'榆林市'}, 
{name:'6109',value:'安康市'}, 
{name:'6110',value:'商洛市'} 
]
}"; 

 
 
这里以jquery异步获取的数据类型——json对象和字符串为依据,分别介绍两种方式获取到的结果处理方式。
 
1.对于服务器返回的JSON字符串,若是jquery异步请求没作类型说明,或者以字符串方式接受,那么须要作一次对象化处理,方式不是太麻烦,就是将该字符串放于eval()中执行一次。这种方式也适合以普通javascipt方式获取json对象,如下举例说明:
 
var dataObj=eval("("+data+")");//转换为json对象
 
为何要 eval这里要添加 “("("+data+")");//”呢?
 
缘由在于:eval自己的问题。 因为json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,因此必须强制性的将它转换成一种表达式。
 
加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将 括号内的表达式(expression)转化为对象,而不是做为语 句(statement)来执行。举一个例子,例如对象字面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始 和结束标记,那么{}将会被认为是执行了一句空语句。因此下面两个执行结果是不一样的:
 
 代码以下:

 代码以下 复制代码
alert(eval("{}"); // return undefined
alert(eval("({})");// return object[Object]

 
 
对于这种写法,在JS中,能够处处看到。
 
如: (function()) {}();  作闭包操做时等。
 
代码以下:

 代码以下 复制代码
alert(dataObj.root.length);//输出root的子对象数量 
$.each(dataObj.root,fucntion(idx,item){ 
if(idx==0){ 
return true; 

//输出每一个root子对象的名称和值 
alert("name:"+item.name+",value:"+item.value); 
}) 

 
 
注:对于通常的js生成json对象,只须要将$.each()方法替换为for语句便可,其余不变。
 
2.对于服务器返回的JSON字符串,若是jquery异步请求将 type(通常为这个配置属性)设为“json”,或者利 用$.getJSON()方法得到服务器返回,那么就不须要eval()方法了,由于这时候获得的结果已是json对象了,只需直接调用该对象便可,这 里以$.getJSON方法为例说明数据处理方法: 
 
代码以下:

 代码以下 复制代码
$.getJSON("http://www.111cn.net/",{param:"gaoyusi"},function(data){ 
//此处返回的data已是json对象 
//如下其余操做同第一种状况 
$.each(data.root,function(idx,item){ 
if(idx==0){ 
return true;//同countinue,返回false同break 

alert("name:"+item.name+",value:"+item.value); 
}); 
});

 
这里特别须要注意的是方式1中的eval()方法是动态执行其中字符串(多是js脚本)的,这样很容易会形成系统的安全问题。因此能够采用一些规避了eval()的第三方客户端脚本库,好比JSON in JavaScript就提供了一个不超过3k的脚本库。

*eval执行的常见错误

---源码

 代码以下 复制代码

console.log("Eval Usage");
var str1_err = "function () {console.log('run fun1')};";
try{
    eval(str1_err);
}catch(e){
    console.log(" Error! eval(str1_err)");
    console.log(e.toString());
}
var str1 = "function fun1() {console.log('run fun1')}; fun1();";
eval(str1);

var str2_err = "{name: 'dzh'}";
var result;
try{
    result = eval(str2_err);
    console.log(result.toString());
    console.log("name: " + result.name);
}catch(e){
    console.log(" Error! eval(str2_err)");
    console.log(e.toString());
}
str2 = "({name: 'dzh'})";
result = eval(str2);
console.log(result.toString());
console.log("name: " + result.name);

---结果

 

Eval Usage
 Error! eval(str1_err)
SyntaxError: Unexpected token (
run fun1
dzh
name: undefined
[object Object]
name: dzh

---分析缘由

1)str1_err说明了定义匿名函数致使的报错; 遇到空的'()', 会报错;

2)str2_err说明了对于'{}',引擎解析时会把括号理解为代码块, 而程序原意是一个对象直接量; 因此经常使用的方式是在'{}'外围加小括号, 那么eval就先执行求值运算, 它就返回对象.

综述, 使用eval时, 要考虑引擎是如何理解传入的字符串代码.

出处:http://www.111cn.net/wy/js-ajax/64587.htm

相关文章
相关标签/搜索