javascript
JavaScript常用函数之Eval()使用
eval()
功能:首先解釋Javascript代碼? 然后執(zhí)行它
用法:Eval(codeString) codeString是包含有javascript語句的字符串,在eval之后使用Javascript引擎編譯。即:eval函數(shù)可以把一個(gè)字符串當(dāng)作一個(gè)javascript表達(dá)式一樣去執(zhí)行它。
eval可以將字符串生成語句執(zhí)行,和SQL的exec()類似。
使用場(chǎng)合:預(yù)先不知道要執(zhí)行什么語句,只有當(dāng)條件和參數(shù)給時(shí)才知道執(zhí)行什么語句,這時(shí)候evaluate就派上用場(chǎng)了。
eg1:
var theEval1="2+3";
var theresult=eval("2+3");
alert("the Eval1 result is:"+theEval1+"and the result is:"+theresult);
如果運(yùn)行程序看到結(jié)果,字符串“2+3”被執(zhí)行了。得到結(jié)果5.
例子:eval(id?+?"_icon.src="/imgs/collapse_up.gif'");
????????????id是之前設(shè)定的參數(shù),而在雙引號(hào)中的字符串則是需要編譯的
????????????引用:
????????????--------------------------------------------------------------------------------
????????????function?tophide(id)?????//id?indicates?menu
????????????{
?????????????????if?(top.topframeset.rows?==?"31,*")
?????????????????{
?????????????????????top.topframeset.rows?=?"86,*";
?????????????????????eval(id?+?"_icon.src="/imgs/collapse_up.gif'");
?????????????????????eval(id?+?"_icon.alt='Collapse?The?Head'");
?????????????????????head.style.display?=?"block"
?????????????????????}
?????????????????else
?????????????????{
?????????????????????top.topframeset.rows?=?"31,*";
?????????????????????eval(id?+?"_icon.src="/imgs/collapse_down.gif'");
?????????????????????eval(id?+?"_icon.alt='Expand?The?Head'");
?????????????????????head.style.display?=?"none"
?????????????????}?
????????????}
????????????如果還是不明白深入認(rèn)識(shí)javascript中的eval函數(shù)
??????????
????????????發(fā)現(xiàn)為本文起一個(gè)合適的標(biāo)題還不是那么容易,呵呵,所以在此先說明下本文的兩個(gè)目的:
????????????(1)介紹javascript中的eval函數(shù)的用法
????????????(2)如何在函數(shù)內(nèi)執(zhí)行全局代碼
???????????先來說eval的用法,內(nèi)容比較簡單,熟悉的可以跳過。
????????????eval函數(shù)接收一個(gè)參數(shù)s,如果s不是字符串,則直接返回s。否則執(zhí)行s語句。如果s語句執(zhí)行結(jié)果是一個(gè)值,則返回此值,否則返回undefined。
????????????需要特別注意的是對(duì)象聲明語法“{}”并不能返回一個(gè)值,需要用括號(hào)括起來才會(huì)返回值,簡單示例如下:
????????????var?code1='"a"?+?2';????//表達(dá)式
????????????var?code2='{a:2}';??????//語句
????????????alert(eval(code1));?????//->'a2'
????????????alert(eval(code2));?????//->undefined
????????????alert(eval('('?+?code2?+?')'));????//->[object?Object]
????????????可以看到,對(duì)于對(duì)象聲明語句來說,僅僅是執(zhí)行,并不能返回值。為了返回常用的“{}”這樣的對(duì)象聲明語句,必須用括號(hào)括住,以將其轉(zhuǎn)換為表達(dá)式,才能返回其值。這也是使用JSON來進(jìn)行Ajax開發(fā)的基本原理之一。在例子中可以清楚的看到,第二個(gè)alert語句輸出的是undefined,而第三個(gè)加了括號(hào)后輸出的是語句表示的對(duì)象。
??????現(xiàn)在來說本文的重點(diǎn),如何在函數(shù)內(nèi)執(zhí)行全局代碼。為了說明這個(gè)問題,先看一個(gè)例子:
????????????var?s='global';????//定義一個(gè)全局變量
????????????function?demo1(){
????????????????eval('var?s="local"');
????????????}
????????????demo1();
????????????alert(s);????//->global
????????????很好理解,上面的demo1函數(shù)等價(jià)于:function?demo1(){var?s='local';},其中定義了一個(gè)局部變量s。
????????????所以最后的輸出是global并不是什么奇怪的事情,畢竟大家都能很清楚的區(qū)分局部變量和全局變量。
????????????仔細(xì)體會(huì)一下,可以發(fā)現(xiàn)eval函數(shù)的特點(diǎn),它總是在調(diào)用它的上下文變量空間(也稱為:包,closure)內(nèi)執(zhí)行,無論是變量定義還是函數(shù)定義都是如此,所以如下的代碼會(huì)產(chǎn)生函數(shù)未定義的錯(cuò)誤:
????????????var?s='function?test(){return?1;}';?????//一個(gè)函數(shù)定義語句
????????????function?demo2(){
????????????????eval(s);
????????????}
????????????demo2();
????????????alert(test());????//->error:test?is?not?defined
????????????這是因?yàn)閠est函數(shù)在局部空間定義,demo2函數(shù)內(nèi)可以訪問到,外面就訪問不到了。
????????????而在實(shí)際的Ajax開發(fā)中,有時(shí)我們需要從服務(wù)器動(dòng)態(tài)獲取代碼來執(zhí)行,以減輕一次載入代碼過多的問題,或者是一些代碼是通過Javascript自身生成的,希望用eval函數(shù)來使其執(zhí)行。
????????????但這樣的動(dòng)態(tài)獲取代碼的工作一般在函數(shù)內(nèi)完成,比如:
????????????function?loadCode(){
????????????????var?code=getCode();
????????????????eval(code);
????????????}
????????????可見eval不可能在全局空間內(nèi)執(zhí)行,這就給開發(fā)帶來了不少問題,也看到過很多人為此郁悶。
????????????不過現(xiàn)在偶終于找到了解決辦法,嘿嘿,可以同時(shí)兼容IE和Firefox,方法如下:
????????????var?X2={}????//my?namespace:)
????????????X2.Eval=function(code){
????????????if(!!(window.attachEvent?&&?!window.opera)){
??????????????//ie
??????????????execScript(code);?
????????????}else{
??????????????//not?ie
??????????????window.eval(code);
????????????}
????????????}
????????????現(xiàn)在如果要想在函數(shù)內(nèi)定義全局代碼,就可以通過調(diào)用X2.Eval(code)方法,一個(gè)例子如下:
????????????var?s='global';
????????????function?demo3(){
????????????X2.Eval('var?s="local"');
????????????}
????????????demo3();
????????????alert(s);?//->'local'
????????????可見,在demo3函數(shù)內(nèi)重新定義了全局變量s="local"。
????????????需要注意的是X2.Eval并不返回值,如果要進(jìn)行表達(dá)式的求值,還是用系統(tǒng)的eval函數(shù)。X2.Eval設(shè)計(jì)為僅做全局代碼定義用。
????????????其實(shí)看到這里,或許有人感覺問題也太容易解決了點(diǎn),呵呵,但發(fā)現(xiàn)這個(gè)辦法倒是需要些運(yùn)氣和技巧的:
????????????(1)對(duì)于IE瀏覽器,默認(rèn)已經(jīng)提供了這樣的函數(shù):execScript,用于在全局空間執(zhí)行代碼,只是知道的人還不多。
????????????(2)對(duì)于Firefox瀏覽器,直接調(diào)用eval函數(shù),則在調(diào)用者的空間執(zhí)行;如果調(diào)用window.eval則在全局空間執(zhí)行。這個(gè)知道的人估計(jì)就更少了。畢竟alert(eval==window.eval)返回true!
????????????Firefox的eval函數(shù)的特點(diǎn)的確是很令人奇怪的,但從javascript規(guī)范中倒也能找到其來源:
????????????If?value?of?the?eval?property?is?used?in?any?way?other?than?a?direct?
????????????call?(that?is,?other?than?by?the?explicit?use?of?its
????????????name?as?an?Identifier?which?is?the?MemberExpression?in?a?
????????????CallExpression),?or?if?the?eval?property?is?assigned?to,
????????????an?EvalError?exception?may?be?thrown.
????????????意思大概就是說eval函數(shù)的執(zhí)行是和調(diào)用者相關(guān)的,但并沒有說其執(zhí)行上下文的問題。所以IE和Firefox孰是孰非也就很難說了,大家知道解決辦法就好
?
轉(zhuǎn)載于:https://www.cnblogs.com/bianyuanzhe/p/5969837.html
總結(jié)
以上是生活随笔為你收集整理的JavaScript常用函数之Eval()使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql auto_increment
- 下一篇: Spring 读取配置文件(二)