本文實例分析了javascript中eval函數用法。分享給大家供大家參考。具體分析如下:
eval()只有一個參數,如果傳入的參數不是字串,則直接傳回這個參數。否則會將字串當成js程式碼進行編譯,如果編譯失敗則拋出語法錯誤(SyntaxError)異常。如果編譯成功則開始執行這段程式碼,並傳回字串中的最後一個表達式或語句的值;如果最後一個表達式或語句沒有值,則最終傳回undefined。如果字串拋出異常,則該異常將把該呼叫傳遞給eval();
eval()最為重要的是,它使用了呼叫它的變數作用域環境,即它尋找變數的值和定義新變數和函數的操作和局部作用域的程式碼完全一樣。
eval("var x = 100"); eval("var y = 11"); console.log(x * y); //x * y == 1100 eval("function foo(x){return Math.pow(x,x);}"); console.log(foo(5)); // 25
eval字串執行時的上下文環境和呼叫函數的上下文環境是一樣的,這不能使其作為函數的一部分來運行:
var foo = function(a){ eval(a); }; foo("return;");
以上程式碼因為執行eval(a)的上下文是全域的,在全域上下文中使用return會拋出語法錯誤:return not in function.
eval()具有修改局部變數的能力,這對於js優化器來說是一個很大的問題。為了讓js解釋器實作更加簡化,ECMAScript3標準規定了任何解釋器都不允許對eval()賦予別名,如果eval()函數透過別名呼叫會拋出一個EvalError異常。
實際上大多數的實作不是這樣的。當透過別名呼叫時,eval()會將其字串當成頂層的全域程式碼來執行。執行程式碼可能會定義新的全域變數和全域函數,或給全域變數賦值,但卻不能使用或修改主呼叫函數中的局部變量,因此不會影響到函數內部的程式碼最佳化。
而在ECMAScript5中,態度有所不同:反對拋出EvalError異常。在ECMAScript5中當直接使用非限定名來呼叫eval()函數時,通常稱為」直接eval(direct eval)」;直接呼叫eval()時,總是在呼叫它的上下文作用域內執行。而其他的間接呼叫則使用全域物件作為其上下文作用域,且無法讀寫和定義局部變數和函數。 (但實際我在firebug測試裡發現,都是修改了全域變數 :( )
需要真正eval來執行程式碼段的場景並不多見,可能更多的會使用全域eval而不是局部eval。
IE9之前的早期版本IE當透過別名呼叫eval()時並不是全域eval,但IE定義了一個execScript()的全域函數來完成全域eval的函數(單核心eval()稍有不同,execScript ()總是回傳null)。
ECMAScript5嚴格模式對eval函數行為施加了更多的限制。在嚴格模式下使用eval或eval執行程式碼以”use strict”指令開始時,eval是私有上下文環境中的局部eval.此外嚴格模式將eval列為保留字,這讓eval()更像一個運算符,不能用一個別名覆蓋eval()函數,且變數名、函數名、函數參數或異常捕獲的參數都不能取名為”eval”.
希望本文所述對大家的javascript程式設計有所幫助。