让eval()全局作用域执行的方法深入研究(javascript)
来源:互联网 发布:数组如何接受数据 编辑:程序博客网 时间:2024/05/17 09:31
eval(str)用来传入一个字符串动态执行一段脚本,这个方法非常有用。当直接用eval()时,作用域为当前作用域,有时候我们需要让它在全局作用域范围内执行,比如ajax返回的脚本字符串,然而浏览器对eval的差异可能使事情刚开始并不是那么顺利,本文通过在7种浏览器(IE, Firefox,Chrome, Safari, Opera)环境中测试,并提出三种解决方案,使这个问题比较完美的解决。
看这一段javascript代码:
function xx(){
var x=1;
window.eval('var x=3;');
document.writeln(x);
}
xx();
在你自己测试和看我接下来的分析之前,先想想,你认为输出结果会是什么呢?是1还是3?
根据本文的标题,可知肯定是在不同浏览器下有不同表现的。
以下是我的实测数据:
var x=1;
window.eval('var x=3;');
document.writeln(x);
}
xx();
可见各浏览器及版本对window.eval()的作用域处理是有差异的。
IE中,window.eval()和eval()一样只在当前作用域生效。
Firefox,Safari,Opera中,直接调用eval()为当前作用域,window.eval()调用为全局作用域。
尤其值得注意的是,Google Chrome 的不同版本之间对于eval的处理也有差异。
如果需要在全局作用域eval()的效果,且通用于所有浏览器,那就得好好变通一下了。
方法之一:
使用IE专有的window.execScript。
如果你碰到这个问题不知所措,并上网搜索,这个方法大概是最先也几乎唯一能搜索到的方法。
window.execScript(sExpression, sLanguage)。
比如上面那一段代码中eval一句如果换成window.execScript('var x=3;');IE中的运行结果就是1了。
非IE内核的浏览器并不支持window.execScript。
IE之所以有这个window.execScript,还和IE能够执行其他语言的脚本有关,通过给不同的sLanguage参数,IE这个方法除能够执行javascript之外,还可以执行vbscript或是其他任何安装过相应解释引擎的脚本如perl,python等。
当需要在局部环境中执行的时候,我们就直接用eval()。
当需要在全局环境中执行的时候,我们可以封装一个通用的函数,就像下面这样:
//在全局环境中执行
function evalGlobal(strScript){
if(window.execScript)window.execScript(strScript);
else window.eval(strScript);
}
就是将IE和非IE区别开来对待。
看起来,问题似乎圆满解决了。但是显然是有问题的,比如上表中的Chrome 1.0也和IE的eval()规则一致,况且还不知道其他浏览器其他版本是否有差异呢,因此,这种方法并不很可靠。
但是如果你有一点完美主义者的倾向,那么事情还不能到此为止,肯定是有更好更简洁的方法的嘛。
不知道阅读此文的你是否有想到呢?
是否和我的想法一致呢?
方法之二:
新建一个<script>元素装载脚本。
这种方法常用来解决innerHTML中的脚本不能运行的问题。但用来解决eval()的作用域问题,恐怕就比较罕见了。
//在全局环境中执行
function evalGlobal(strScript){
var a=document.createElement("script");
a.type="text/javascript";
a.text=strScript;
document.getElementsByTagName("head")[0].appendChild(a);
}
虽然这个方法有点变态,需要新增一个<script>元素,但优点是各种浏览器及版本通用,比方法一要好一些了。。
但是如果你有再多一点完美主义者的倾向,那么事情还不能到此为止,毕竟添加了一个HTML元素嘛,影响了页面原本的DOM结构。
那么是不是有更好更简洁的方法的呢?答案是肯定的。经过我的研究,找到了同时具备简洁和可靠的方法三。
不知道阅读此文的你是否有想到呢?
是否和我的想法一致呢?
方法之三:
还是eval。回归原生态。
我们别忘了javascript里面有一个改变上下文环境的关键字,强大的with.
原来事情可以更简单更有效!
//在全局环境中执行
function evalGlobal(strScript){
with(window)eval(strScript);
}
看看,都这么简单了,我们完全可以不用封装为函数了,直接在代码中用。
文章最开始的代码我们就可以这样来了:
function xx(){
eval('var x=1;'); //局部变量
with(window){eval('var x=3;');} //全局变量
//也可以用封装的 evalGlobal('var x=3');
document.writeln(x); //1 局部变量
document.writeln(window.x); //3 全局变量
}
xx();
特别:
有时候,我们eval()要求既不是在全局执行,也不是在当前作用域执行,而是在父对象或子对象中执行,这时,用with(objContext)eval(strScript)就更加是不可替代的选择了。
总结:
让eval()全局作用域执行的方法主要有:
(1)window.execScript + window.eval 级别:弱。 缺点:不简洁,不可靠,不通用。
(2)document.createElement("script") 级别:凑合。缺点:不简洁,不干净。优点:可靠,通用。
(3)with(objContext)eval(strScript) 级别:最佳。优点:简洁,干净,可靠,通用。
N整一个表格比较清楚:
事情到这里,才可以去休息一下了。
- 让eval()全局作用域执行的方法深入研究
- 让eval()全局作用域执行的方法深入研究(javascript)
- js eval() 全局作用域
- JavaScript全局函数eval的用法
- Eval方法(执行Javascript字串命令)
- Eval方法(执行Javascript字串命令)
- Eval方法(执行Javascript字串命令)
- Eval方法(执行Javascript字串命令)
- javascript:Global全局对象,编码解码,eval方法
- javascript的eval()方法
- Javascript中eval()函数的作用
- 深入理解javascript(13):作用域和执行上下文
- 深入区分JavaScript中的作用域和执行环境
- javascript eval函数的深入认识
- 全局函数的作用域和执行环境
- 全局eval的实现
- DataBinder.Eval方法研究
- DataBinder.Eval方法研究
- c#复制和删除文件夹
- 《Understanding Linux Network Internals》 第一章序言
- 计算云与云计算
- 配置Apache服务器详解
- 个人的心血和经验——Eclipse + CDT + MinGW开发环境配置及问题解决
- 让eval()全局作用域执行的方法深入研究(javascript)
- JSON 入门指南【转】
- OO设计原则(摘自:《Head First Design Pattern》)
- Linux系统信息查看命令大全
- Windows API一日一练(27)SetBkMode函数
- exec 命令的相关问题,包括空格的文件名
- 多线程 循环 更新 网络状态
- hql delete
- Jquery Validation Engine 与UpdatePanel冲突的问题