今天碰到一个问题,ajax请求程序后,返回的结果:{a:1,b:2},程序员说是对象,但是我得到的结果是string,最后用eavl来转化,然后从这里面学到了以下两点知识:
1.字符串与对象的区分
'{a:1}|{b:2}'.split('|')[0]得到的是字符串,原因是:数组里面每个项是由'{a:1}|{b:2}'这个字符串转化成的,所以里面每个项都是字符串。字符串转化成数组时,数组项还是字符串
[{a:1},{b:2}][0]得到的是object
2.eavl()的使用
eval()接受一个参数,如果这个参数不是字符串的话,直接近返回该参数,如果是字符串的话,就执行这个这个字符串,执行结果后能得到值的话就直接返回,否则就返回undefined,如果参数是对象语句{a:1}的话,则不能返回该对象,如果想返回对象的话,必须将{a:1}这个语句转化为表达式:例 下面:
eavl('{a:1}')是执行,得到1,将里面的内容当成是一段代码执行了,没有返回值
eavl('('+{a:1}+')'),eavl会将里面的内容当成object解析,返回的结果是object
eval()函数有个特点,他总是在调用他的上下文变量内执行,无论是变量定义还是函数定义都是如此
var s='function test(){return 1;}'; //一个函数定义语句
function demo2(){
eval(s);
}
demo2();
alert(test()); //->error:test is not defined
这是因为test函数在局部空间定义,demo2函数内可以访问到,外面就访问不
到了。
而在实际的Ajax开发中,有时我们需要从服务器动态获取代码来执行,以减
轻一次载入代码过多的问题,或者是一些代码是通过Javascript自身生成的,希
望用eval函数来使其执行。
但这样的动态获取代码的工作一般在函数内完成,比如:
function loadCode(){
var code=getCode();
eval(code);
}
可见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(code)方法,
一个例子如下:
var s='global';
function demo3(){
X2.Eval('var s="local"');
}
demo3();
alert(s); //->'local'
可见,在demo3函数内重新定义了全局变量s="local"。
需要注意的是X2.Eval并不返回值,如果要进行表达式的求值,还是用系统的
eval函数。X2.Eval设计为仅做全局代码定义用。
其实看到这里,或许有人感觉问题也太容易解决了点,呵呵,但发现这个办
法倒是需要些运气和技巧的:
(1)对于IE浏览器,默认已经提供了这样的函数:execScript,用于在全局
空间执行代码,只是知道的人还不多。
(2)对于Firefox浏览器,直接调用eval函数,则在调用者的空间执行;如
果调用 window.eval则在全局空间执行。这个知道的人估计就更少了。毕
竟alert(eval==window.eval)返回true!