JS中Eval解析JSON字符串的一個(gè)小問(wèn)題
之前寫(xiě)過(guò)一篇 關(guān)于 JSON 的介紹文章,里面談到了 JSON 的解析。我們都知道,高級(jí)瀏覽器可以用 JSON.parse() API 將一個(gè) JSON 字符串解析成 JSON 數(shù)據(jù),稍微欠妥點(diǎn)的做法,我們可以用eval() 函數(shù)。
JSON (JavaScript Object Notation)一種簡(jiǎn)單的數(shù)據(jù)格式,比xml更輕巧。 JSON 是 JavaScript 原生格式,這意味著在 JavaScript 中處理 JSON 數(shù)據(jù)不需要任何特殊的 API 或工具包。
JSON的規(guī)則很簡(jiǎn)單: 對(duì)象是一個(gè)無(wú)序的“‘名稱(chēng)/值'對(duì)”集合。一個(gè)對(duì)象以“{”(左括號(hào))開(kāi)始,“}”(右括號(hào))結(jié)束。每個(gè)“名稱(chēng)”后跟一個(gè)“:”(冒號(hào));“‘名稱(chēng)/值' 對(duì)”之間使用“,”(逗號(hào))分隔
var str = '{"name": "hanzichi", "age": 10}';
var obj = eval('(' + str + ')');
console.log(obj); // Object {name: "hanzichi", age: 10}
是否注意到,向 eval() 傳參時(shí),str 變量外裹了一層小括號(hào)?為什么要這樣做?
我們先來(lái)看看 eval 函數(shù)的定義以及使用。
eval() 的參數(shù)是一個(gè)字符串。如果字符串表示了一個(gè)表達(dá)式,eval() 會(huì)對(duì)表達(dá)式求值。如果參數(shù)表示了一個(gè)或多個(gè) JavaScript 聲明, 那么 eval() 會(huì)執(zhí)行聲明。不要調(diào)用 eval() 來(lái)為算數(shù)表達(dá)式求值; JavaScript 會(huì)自動(dòng)為算數(shù)表達(dá)式求值。
簡(jiǎn)單地說(shuō),eval 函數(shù)的參數(shù)是一個(gè)字符串,如果把字符串 "noString" 化處理,那么得到的將是正常的可以運(yùn)行的 JavaScript 語(yǔ)句。
怎么說(shuō)?舉個(gè)栗子,如下代碼:
var str = "alert('hello world')";
eval(str);
執(zhí)行后彈出 "hello world"。我們把 str 變量 "noString" 化,粗暴點(diǎn)的做法就是去掉外面的引號(hào),內(nèi)部調(diào)整(轉(zhuǎn)義等),然后就變成了:
alert('hello world')
very good!這是正常的可以運(yùn)行的 JavaScript 語(yǔ)句!運(yùn)行之!
再回到開(kāi)始的問(wèn)題,為什么 JSON 字符串要裹上小括號(hào)。如果不加,是這個(gè)樣子的:
var str = '{"name": "hanzichi", "age": 10}';
var obj = eval(str); // Uncaught SyntaxError: Unexpected token :
恩,報(bào)錯(cuò)了。為什么會(huì)報(bào)錯(cuò)?試試把 str "noString" 化,執(zhí)行一下:
{"name": "hanzichi", "age": 10}; // Uncaught SyntaxError: Unexpected token :
毫無(wú)疑問(wèn),一個(gè) JSON 對(duì)象或者說(shuō)是一個(gè)對(duì)象根本就不是能執(zhí)行的 JavaScript 語(yǔ)句!等等,試試以下代碼:
var str = '{name: "hanzichi"}';
var obj = eval(str);
console.log(obj); // hanzichi
這又是什么鬼?但是給 name 加上 "" 又報(bào)錯(cuò)?
var str = '{"name": "hanzichi"}';
var obj = eval(str); // Uncaught SyntaxError: Unexpected token :
console.log(obj);
好吧,快暈了,其實(shí)還是可以將 str "nostring" 化,看看是不是能正確執(zhí)行的 JavaScript 語(yǔ)句。前者的結(jié)果是:
{name: "hanzichi"}
這確實(shí)是一條合法的 JavaScript 語(yǔ)句。{} 我們不僅能在 if、for 語(yǔ)句等場(chǎng)景使用,甚至可以在任何時(shí)候,因?yàn)?ES6 之前 JavaScript 只有塊級(jí)作用域,所以對(duì)于作用域什么的并不會(huì)有什么沖突。去掉 {} 后 name: "hanzichi" 也是合法的語(yǔ)句,一個(gè) label 語(yǔ)句,label 語(yǔ)句在跳出嵌套的循環(huán)中非常好用,具體可以參考 label,而作為 label 語(yǔ)句的標(biāo)記,name 是不能帶引號(hào)的,標(biāo)記能放在 JavaScript 代碼的任何位置,用不到也沒(méi)關(guān)系。
一旦一個(gè)對(duì)象有了兩個(gè) key,比如 {name: "hanzichi", age: 10},ok,兩個(gè) label 語(yǔ)句?將 "hanzhichi" 以及 10 分別看做是語(yǔ)句,但是 語(yǔ)句之間只能用封號(hào)連接?。ū磉_(dá)式之間才能用逗號(hào))。所以改成下面這樣也是沒(méi)有問(wèn)題的:
var str = '{name: "hanzichi"; age: 10}';
var obj = eval(str);
console.log(obj); // 10
越扯越遠(yuǎn),文章開(kāi)頭代碼的錯(cuò)誤的原因是找到了,為什么套個(gè)括號(hào)就能解決呢?簡(jiǎn)單來(lái)說(shuō),() 會(huì)把語(yǔ)句轉(zhuǎn)換成表達(dá)式,稱(chēng)為語(yǔ)句表達(dá)式。括號(hào)里的代碼都會(huì)被轉(zhuǎn)換為表達(dá)式求值并且返回,對(duì)象字面量必須作為表達(dá)式而存在。
本文并不會(huì)大談表達(dá)式,關(guān)于表達(dá)式,可以參考文末鏈接。值得記住的一點(diǎn)是,表達(dá)式永遠(yuǎn)有一個(gè)返回值。大部分表達(dá)式會(huì)包裹在() 內(nèi),小括號(hào)內(nèi)不能為空,如果有多個(gè)表達(dá)式,用逗號(hào)隔開(kāi),也就是所謂的逗號(hào)表達(dá)式,會(huì)返回最后一個(gè)的值。
以上所述是小編給大家介紹了JS中Eval解析JSON字符串的一個(gè)小問(wèn)題,希望對(duì)大家有所幫助!
- javascript使用eval或者new Function進(jìn)行語(yǔ)法檢查
- eval(function(p,a,c,k,e,d)系列解密javascript程序
- js eval函數(shù)使用,js對(duì)象和字符串互轉(zhuǎn)實(shí)例
- js中的eval()函數(shù)把含有轉(zhuǎn)義字符的字符串轉(zhuǎn)換成Object對(duì)象的方法
- AngularJs $parse、$eval和$observe、$watch詳解
- 關(guān)于動(dòng)態(tài)執(zhí)行代碼(js的Eval)實(shí)例詳解
- JS使用eval()動(dòng)態(tài)創(chuàng)建變量的方法
- javascript中JSON.parse()與eval()解析json的區(qū)別
- 深入淺析JSON.parse()、JSON.stringify()和eval()的作用詳解
- 詳解Vue.js搭建路由報(bào)錯(cuò) router.map is not a function
- 淺談js中function的參數(shù)默認(rèn)值
- 淺析JS中對(duì)函數(shù)function的理解(基礎(chǔ)篇)
- 深入理解JS中的Function.prototype.bind()方法
- JS中注入eval, Function等系統(tǒng)函數(shù)截獲動(dòng)態(tài)代碼
相關(guān)文章
JS/jQuery實(shí)現(xiàn)獲取時(shí)間的方法及常用類(lèi)完整示例
這篇文章主要介紹了JS/jQuery實(shí)現(xiàn)獲取時(shí)間的方法及常用類(lèi),結(jié)合完整實(shí)例形式分析了javascript針對(duì)日期時(shí)間的獲取、轉(zhuǎn)換、計(jì)算與檢測(cè)相關(guān)操作技巧,需要的朋友可以參考下2019-03-03
JavaScript和jQuery獲取input框的絕對(duì)位置實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇JavaScript和jQuery獲取input框的絕對(duì)位置實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
wangEditor編輯器失去焦點(diǎn)后仍然可以在原位置插入圖片分析
本文給大家?guī)?lái)的是一款非常不錯(cuò)的富文本編輯器WangEditor,他最大的特點(diǎn)是它在ie6,7,8上都可以做到失去焦點(diǎn)后仍然可以在原位置插入圖片,而且代碼量很少,下面我們就來(lái)分析下他是如何實(shí)現(xiàn)的呢2015-05-05
JavaScript實(shí)現(xiàn)文本中間縮略的兩種方案
項(xiàng)目中經(jīng)常會(huì)遇到縮略展示文字的場(chǎng)景,即要求文字在一行不換行展示,超出自動(dòng)展示...,常用的展示效果有兩種,文字中間縮略以及文字末尾縮略,本文將通過(guò)代碼示例給大家詳細(xì)的講一下這兩種方案,需要的朋友可以參考下2024-06-06
localResizeIMG先壓縮后使用ajax無(wú)刷新上傳(移動(dòng)端)
隨著技術(shù)的發(fā)展,移動(dòng)設(shè)備像素越來(lái)越高,但是這么大的圖片怎么上傳呢?下面小編就給大家一起學(xué)習(xí)移動(dòng)端圖片上傳的方法之localResizeIMG先壓縮后使用ajax無(wú)刷新上傳,需要的朋友可以參考下2015-08-08
解決使用layui對(duì)select append元素?zé)o效或者未及時(shí)更新的問(wèn)題
今天小編就為大家分享一篇解決使用layui對(duì)select append元素?zé)o效或者未及時(shí)更新的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09
JS簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加HTML標(biāo)記的方法示例
這篇文章主要介紹了JS簡(jiǎn)單實(shí)現(xiàn)動(dòng)態(tài)添加HTML標(biāo)記的方法,結(jié)合實(shí)例形式分析了JavaScript使用createElement()方法針對(duì)頁(yè)面元素進(jìn)行動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-04-04

