4.12 運算式計算eval() eval()可以解釋運行由JavaScript原始碼組成的字串,併產生一個值。eval()是全域函數。
4.12.1 eval() eval()只有一個參數,如果傳入的參數不是字串,它直接返回這個參數。如果參數是字串,它會把字串當成JavaScript代碼進行編譯,如果編譯失敗則拋出一個語法錯誤異常。如果編譯成功則開始執行這段代碼,並返回字串中的最後一個運算式或語句的值,如果最後一個運算式或語句沒有值,則最終返回undefined。如果字串拋出一個異常,這個異常將把該調用傳遞給eval()。 eval()使用了調用它的變數範圍環境。它尋找變數的值和定義新變數和函數的操作和局部範圍中的代碼完全一樣。例如: 定義一個局部變數x, 調用eval(“x”),會返回局部變數的值; 調用eval(“x+1”),改變局部變數的值; 調用eval(“var y = 3;”),聲明一個新的局部變數y; eval(“function f(){ return x+1; }”)聲明一個局部函數; 如果在最頂層代碼中代用eval(),它會作用於全域變數和全域函數。 *傳遞給eval()的字串必須在文法上講得通---不能通過eval()往函數中任意粘貼程式碼片段,比如eval(“return;”)是沒有意義的,因為return只有在函數中才起作用,並且eval()的字串執行時的上下文環境和調用函數的上下文環境是一樣的,這不能使其作為函數的一部分來運行。如果字串作為一個單獨的指令碼是有語義的(如x = 0),那麼將其傳遞給eval()作參數是完全沒有問題的,否則將會拋出語法錯誤異常。 var foo =function(a){ eval(a); }; foo("return;"); //SyntaxError: return not in function foo(" x= 0;"); //undefined |
4.12.2 全域eval() ECMAScript 3標準規定了任何解譯器都不允許對eval()賦予別名。,如果eval()通過別名調用,則會拋出一個EvalError異常。 ECMAScript 5反對使用EvalError,並且規範了eval()的行為。直接調用eval()時,它是在調用它的上下文範圍內執行。其他間接調用則使用全域對象作為其上下文範圍。,並且無法讀、寫、定義局部變數和函數。 var geval = eval; var x = "globala" ,y = "globalb"; function f(){ var x = "locala"; eval("x += 'changed';"); //局部eval return x; } function g(){ var y = "localb"; geval("y += 'changed';"); //全域eval return y; } f(); // localachanged x; //globala g(); //locallb y; //globalbchanged |
4.12.3 嚴格eval() ECMASript 5strict 模式對eval()的行為施加了更多限制。在strict 模式下調用eval(),或者eval()執行的程式碼片段以“use strict”指令開始,這裡的eval()是私人上下文環境中的局部eval,也就是說,在strict 模式下,eval執行的程式碼片段可以查詢或更改局部變數,但不能在局部範圍中定義新的變數或函數。 |