首頁  >  文章  >  web前端  >  JavaScript中eval的使用詳解

JavaScript中eval的使用詳解

黄舟
黄舟原創
2017-11-23 11:00:081976瀏覽

在我們日常開發工作中,JavaScript中的eval使用,相信很多小伙伴們,都有所了解,但是對於剛剛JavaScript的小伙伴們來說eval的用法就有點陌生,今天我們就帶大家詳細的講解下JavaScript中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]

可以看到,對於物件宣告語句來說,只是執行,並不能傳回值。為了傳回常用的「{}」這樣的物件宣告語句,必須用括號括住,以將其轉換為表達式,才能傳回其 值。這也是使用JSON來進行Ajax開發的基本原理之一。在例子中可以清楚的看到,第二個alert語句輸出的是undefined,而第三個加了括號 後輸出的是語句表示的物件。
現在來說本文的重點,如何在函數內執行全域程式碼。為了說明這個問題,先看一個例子:

程式碼如下:

var s='global'; //定义一个全局变量 
function demo1(){ 
eval('var s="local"'); 
} 
demo1(); 
alert(s); //->global

很好理解,上面的demo1函數等價於:function demo1(){var s=' local';},其中定義了一個局部變數s。
所以最後的輸出是global並不是什麼奇怪的事情,畢竟大家都能很清楚的區分局部變數和全域變數。
仔細體會一下,可以發現eval函數的特點,它總是在呼叫它的上下文變數空間(也稱為:包,closure)內執行,無論是變數定義還是函數定義都是如此,所以如下的程式碼會產生函數未定義的錯誤:

程式碼如下:

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(){ 
varcode=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_r(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!
Firefox的eval函數的特點的確是很奇怪的,但從javascript規範中倒也能找到其來源:

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函數的執行是和調用者相關的,但並沒有說其執行上下文的問題。所以IE和Firefox孰是孰非也就很難說了,大家知道解決方法就好。

總結:

本文透過具體的範例為大家展示了JavaScript中eval的使用、相信小夥伴們對eval的使用有了進一步的了解與認識,希望對你的工作有幫助!

相關推薦:

#JavaScript中的eval()函數傳回值與變數環境用法實例詳解

淺聊eval()的作用與作用域

JavaScript如何使用eval()函數計算JavaScript字串實例詳解

以上是JavaScript中eval的使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn