eval函數(shù)的工作原理
eval函數(shù)會評估一個給定的含有JavaScript代碼的字符串,并且試圖去執(zhí)行包含在字符串里的表達(dá)式或者一系列的合法的JavaScript語句。eval函數(shù)將把最后一個表達(dá)式或者語句所包含的值或引用作為返回值。
舉例說明
var bar = 'bar';
var foobar = eval('"foo" + bar');
alert(foobar);
var bar = 'bar';
var foobar = eval('if(bar == "bar") {bar="foo-bar";} else {bar = "bar-foo";}');
alert(foobar);bar = 'foo';
foobar = eval('if(bar == "bar") {bar="foo-bar";} else {bar = "bar-foo";}');
alert(foobar);
JSON的格式
JSON的格式是由大括號和由冒號(:)構(gòu)成的名值對所組成的。注意JSON格式與對象字面量 (object literals) 的區(qū)別:JSON的名字部分嚴(yán)格用引號+名字來表示。
舉例說明
var objectLiteral = {
name: "Objector.L",
age: "24",
special: "JavaScript",
sayName: function() {
return this.name;
}
};
var jsonFormat = {
"summary": "Blogs",
"blogrolls": [
{
"title": "Explore JavaScript",
"link": "http:///"
},
{
"title": "Explore JavaScript",
"link": "http:///"
}
]
};
eval和JSON
由于Ajax的興起,JSON這種輕量級的數(shù)據(jù)格式作為客戶端與服務(wù)器之間的傳輸格式逐漸地流行起來,進(jìn)而出現(xiàn)的問題是如何將服務(wù)器端構(gòu)建好的JSON數(shù)據(jù)轉(zhuǎn)化為可用的JavaScript對象。利用eval函數(shù)無疑是一種簡單而直接的方法。在轉(zhuǎn)化的時(shí)候需要將JSON字符串的外面包裝一層圓括號:
var jsonObject = eval("(" + jsonFormat + ")");
為什么要加括號?
加上圓括號的目的是迫使eval函數(shù)在評估JavaScript代碼的時(shí)候強(qiáng)制將括號內(nèi)的表達(dá)式(expression)轉(zhuǎn)化為對象,而不是作為語句(statement)來執(zhí)行。舉一個例子,例如對象字面量{},如若不加外層的括號,那么eval會將大括號識別為JavaScript代碼塊的開始和結(jié)束標(biāo)記,那么{}將會被認(rèn)為是執(zhí)行了一句空語句。所以下面兩個執(zhí)行結(jié)果是不同的:
alert(eval("{}");
alert(eval("({})");
JSON格式的名字部分為什么要加引號?
因?yàn)閑val函數(shù)會將{foo:”bar”}解釋成合法的JavaScript語句,而非表達(dá)式。但是人們往往想要的是讓eval將這段代碼解釋成一個對象。所以JSON格式會強(qiáng)制你去在名字的外側(cè)加上引號再結(jié)合圓括號,這樣eval就不會錯誤的將JSON解釋成代碼塊。
舉例說明
alert(eval('{foo:"bar"}'));
alert(eval('({"foo": "bar"})'));
結(jié)論
理解eval的工作原理和json的嚴(yán)格的限定格式,合理結(jié)合eval和json應(yīng)用于JavaScript的數(shù)據(jù)傳遞和對象轉(zhuǎn)換。
following this format:
eval('{' + jsonString + ')');