首頁  >  文章  >  web前端  >  JS中Eval解析JSON字串的一個小問題_javascript技巧

JS中Eval解析JSON字串的一個小問題_javascript技巧

WBOY
WBOY原創
2016-05-16 15:14:311568瀏覽

之前寫過一篇 關於 JSON 的介紹文章,裡面談到了 JSON 的解析。我們都知道,高階瀏覽器可以用 JSON.parse() API 將一個 JSON 字串解析成 JSON 數據,稍微欠妥點的做法,我們可以用eval() 函數。

JSON (JavaScript Object Notation)一種簡單的資料格式,比xml更輕巧。 JSON 是 JavaScript 原生格式,這表示在 JavaScript 中處理 JSON 資料不需要任何特殊的 API 或工具包。

JSON的規則很簡單: 物件是一個無序的「『名稱/值』對」集合。一個物件以「{」(左括號)開始,「}」(右括號)結束。每個「名稱」後面跟著一個「:」(冒號);「『名稱/值' 對」之間使用「,」(逗號)分隔

var str = '{"name": "hanzichi", "age": 10}';
var obj = eval('(' + str + ')');
console.log(obj); // Object {name: "hanzichi", age: 10}

是否注意到,向 eval() 傳參時,str 變數外裹了一層小括號?為什麼要這樣做?

我們先來看看 eval 函數的定義以及使用。

eval() 的參數是一個字串。如果字串表示了一個表達式,eval() 會對表達式求值。如果參數表示了一個或多個 JavaScript 聲明, 那麼 eval() 就會執行聲明。不要呼叫 eval() 來為算數運算式求值; JavaScript 會自動為算數運算式求值。

簡單地說,eval 函數的參數是一個字串,如果把字串 "noString" 化處理,那麼得到的將是正常的可以運行的 JavaScript 語句。

怎麼說?舉個栗子,如下碼:

var str = "alert('hello world')";
eval(str);

執行後彈出 "hello world"。我們把 str 變數 "noString" 化,粗暴點的做法就是去掉外面的引號,內部調整(轉義等),然後就變成了:

alert('hello world')

very good!這是正常的可以運行的 JavaScript 語句!運行之!

再回到開始的問題,為什麼 JSON 字串要包裹小括號。如果不加,是這個樣子的:

var str = '{"name": "hanzichi", "age": 10}';
var obj = eval(str); // Uncaught SyntaxError: Unexpected token :

恩,報錯了。為什麼會報錯?試試把 str "noString" 化,執行一下:

{"name": "hanzichi", "age": 10}; // Uncaught SyntaxError: Unexpected token :

毫無疑問,一個 JSON 物件或是說是一個物件根本就不是能執行的 JavaScript 語句!等等,試試以下程式碼:

var str = '{name: "hanzichi"}';
var obj = eval(str);
console.log(obj); // hanzichi

這又是什麼鬼?但給 name 加上 "" 又報錯?

var str = '{"name": "hanzichi"}';
var obj = eval(str); // Uncaught SyntaxError: Unexpected token :
console.log(obj); 

好吧,快暈了,其實還是可以將 str "nostring" 化,看看是不是能正確執行的 JavaScript 語句。前者的結果是:

{name: "hanzichi"}

這確實是一條合法的 JavaScript 語句。 {} 我們不僅能在 if、for 語句等場景使用,甚至可以在任何時候,因為 ES6 之前 JavaScript 只有區塊級作用域,所以對於作用域什麼的並不會有什麼衝突。去掉{} 後name: "hanzichi" 也是合法的語句,一個label 語句,label 語句在跳出巢狀的迴圈中非常好用,具體可以參考label,而作為label 語句的標記,name 是不能帶引號的,標記能放在JavaScript 程式碼的任何位置,用不到也沒關係。

一旦一個物件有了兩個 key,例如 {name: "hanzichi", age: 10},ok,兩個 label 語句?將 "hanzhichi" 以及 10 分別看做是語句,但是 語句之間只能用封號連接! (表達式之間才能用逗號)。所以改成下面這樣也是沒有問題的:

var str = '{name: "hanzichi"; age: 10}';
var obj = eval(str); 
console.log(obj); // 10

越扯越遠,文章開頭程式碼的錯誤的原因是找到了,為什麼套個括號就能解決呢?簡單來說,() 會把語句轉換成表達式,稱為語句表達式。括號裡的程式碼都會轉換為表達式求值並且傳回,物件字面量必須作為表達式而存在。

本文並不會大談表達式,關於表達式,可以參考文末連結。值得記住的一點是,表達式永遠有一個回傳值。大部分錶達式會包裹在() 內,小括號內不能為空,如果有多個表達式,用逗號隔開,也就是所謂的逗號表達式,會傳回最後一個的值。

以上所述是小編給大家介紹了JS中Eval解析JSON字串的一個小問題,希望對大家有幫助!

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