javascript中的eval函式

2021-06-29 03:05:34 字數 1477 閱讀 5102

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)");

console.log(foo(5)); // 25

eval字串執行時的上下文環境和呼叫函式的上下文環境是一樣的,這不能使其作為函式的一部分來執行:

var foo = function

(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中的this詳解

this屬於js的底層知識,了解this之後,能夠實現一些基本的功能,但是感覺最重要的是,this是物件導向必不可少的組成部分,如果希望能夠逐漸的掌握物件導向,this必然是不可少的。檢視this指向的一句話法則 永遠指向其所在函式的所有者如果沒有所有者時,指向window。理解this的要點 關鍵...

JavaScript中的setInterval用法

setinterval function,interval arg1,arg2,argn setinterval object,methodname,interval arg1,arg2,argn 第一種格式是標準動作面板中setinterval函式的預設語法,第二種格式是在專家模式動作中使用的方法...

JavaScript中的陣列

陣列 引數 返回值原陣列是否改變 1 向陣列尾部新增push 引數可以是乙個或多個 返回值是新增後陣列的長度 原陣列改變 2 刪除陣列的最後一項pop 沒有引數 返回值是刪除的那個數 原陣列改變 3 向陣列的頭部新增unshift 引數可以是乙個或多個 返回值是新增後陣列的長度 原陣列改變 4 刪除...