最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

【趣味JavaScript】我的天! 居然工作了5年的前端開(kāi)發(fā)都不知道eval函數(shù)其中暗藏玄機(jī)!

2023-07-14 09:38 作者:極客小俊GeekerJun  | 我要投稿

?? 作者:極客小俊
?? 把邏輯思維轉(zhuǎn)變?yōu)榇a的技術(shù)博主



eval()函數(shù)介紹

首先你要知道在JSeval()函數(shù)是用來(lái)干嘛的!

它主要的功能就是將一個(gè)JS字符串解析,然后把它作為腳本代碼來(lái)執(zhí)行, 要知道字符串始終就是字符串是不能被直接執(zhí)行的!

有了eval()函數(shù)就可以做到, 它的使用語(yǔ)法也很簡(jiǎn)單!

eval(字符串參數(shù));

參數(shù)解釋

傳遞的參數(shù)其實(shí)是要執(zhí)行的 JavaScript代碼字符串形式!

它的返回值也就是通過(guò)計(jì)算字符串得到可執(zhí)行JS代碼腳本

舉個(gè)栗子

這里有一段代碼

var code='var x=10;var y=20;console.log(x*y)';

如果直接執(zhí)行或打印上面的code變量 那么只能直接輸出這個(gè)字符串

如圖

并且從字符串中的內(nèi)容上看,很明顯是一段JS代碼

那么我們就可以使用eval()函數(shù) 來(lái)讓它變成一個(gè)可執(zhí)行的JS腳本

代碼如下

var code='var x=10;var y=20;console.log(x*y)';
eval(code);

如圖



eval()函數(shù)特別的使用方法以及原理

按照以上這樣操作,我們只要把可執(zhí)行的JS字符串丟給eval()函數(shù)不就行了嗎?

那為什么有些時(shí)候還要加什么小括號(hào)()?

也就是為什么還要加()變成 eval('('+變量名+')')呢? ?很多新手會(huì)在這里犯困惑!

那是因?yàn)?code>如果字符串中的語(yǔ)法不正確,eval() 函數(shù)會(huì)拋出語(yǔ)法錯(cuò)誤

w3c文檔上也有明確的說(shuō)明

如圖

那到底如何來(lái)理解這個(gè)意思呢? 什么叫不是合法的表達(dá)式和語(yǔ)句呢?

舉個(gè)栗子

var data ='{"張三"}';
console.log("類型為:"+typeof data);
console.log(eval(data));

以上打印結(jié)果如下圖:


但是如果我寫(xiě)成以下這樣就會(huì)給你報(bào)一個(gè)SyntaxError語(yǔ)法錯(cuò)誤的提示!


如圖

可是你可能會(huì)想,這不就是我們常見(jiàn)的JSON數(shù)據(jù)嗎,雖然是字符串, 不能直接使用,但是使用eval()函數(shù)處理以下應(yīng)該可以直接調(diào)用了呀,可為什么會(huì)報(bào)錯(cuò)呢?

原理分析

首先JSON是一種數(shù)據(jù)格式,它用于存儲(chǔ)交換數(shù)據(jù)用的,這沒(méi)問(wèn)題吧!

JSON中,數(shù)據(jù)被表示為鍵值對(duì),這里的之間用冒號(hào)分隔,鍵值對(duì)之間用逗號(hào)分隔,

并且整個(gè)數(shù)據(jù)被包含在大括號(hào){}當(dāng)中,這也是JSON數(shù)據(jù)格式標(biāo)準(zhǔn) 也沒(méi)問(wèn)題對(duì)吧!

可是呢eval()函數(shù)會(huì)把這個(gè)字符串{......}當(dāng)成一個(gè)Javascript語(yǔ)句塊來(lái)處理, 那么顯然這樣解析就會(huì)報(bào)錯(cuò)!

我們平常寫(xiě)JS語(yǔ)句塊都是以下的方式

for(){
? ?..語(yǔ)句塊..
}

if(){
? ?..語(yǔ)句塊..
}

while(){
? ?..語(yǔ)句塊..
}

這些都是語(yǔ)句塊,也可以叫復(fù)合語(yǔ)句塊

復(fù)合語(yǔ)句塊是指由多個(gè)語(yǔ)句組成的語(yǔ)句塊,它們通常被包含在一對(duì)花括號(hào){....}

在開(kāi)發(fā)中,復(fù)合語(yǔ)句塊通常用于控制程序的流程

例如上面說(shuō)到的: if、for、while 等語(yǔ)句的語(yǔ)句體就是一個(gè)復(fù)合語(yǔ)句塊

復(fù)合語(yǔ)句塊可以包含變量定義、表達(dá)式、控制語(yǔ)句等多種語(yǔ)句,

這些語(yǔ)句將按照順序依次執(zhí)行,直到復(fù)合語(yǔ)句塊的結(jié)尾處!


那么你有見(jiàn)過(guò)以下這樣的復(fù)合語(yǔ)句塊塊嗎?

{
? ?"username":"zhangsan"
}

我們來(lái)運(yùn)行看看效果

如圖

那么很明顯,從JS基本復(fù)合語(yǔ)句塊的語(yǔ)法上,這就不能這樣寫(xiě)對(duì)吧! ?從JS語(yǔ)句的語(yǔ)法上講不通呀!

所以說(shuō)剛剛我們目的是讓eval()函數(shù)JSON字符串解析為一個(gè)對(duì)象,而不是解析為語(yǔ)句塊 明白了吧!

你也可以理解為是一種強(qiáng)制性的轉(zhuǎn)換成表達(dá)式來(lái)進(jìn)行表示!

如果我們不加括號(hào),那么eval()函數(shù)就可能會(huì)將 這個(gè)JSON字符串解析為JS語(yǔ)句塊的形式來(lái)進(jìn)行執(zhí)行,那語(yǔ)句塊按照這樣取寫(xiě)肯定是錯(cuò)誤的語(yǔ)法呀,從而拋出語(yǔ)法錯(cuò)誤!


那么就像上面的案例一樣我們也可以讓它正常執(zhí)行成為一個(gè)JSON對(duì)象

代碼如下

({
? ?"username":"zhangsan"
})

給它加上一個(gè)()括號(hào) 嗯嗯 這里非常的精妙!

加了()括號(hào)以后就表示一個(gè)整體, 讓JS引擎知道這是一個(gè)JSON對(duì)象而非一個(gè)語(yǔ)句塊, 自然就不會(huì)報(bào)錯(cuò)了!

我們也可以賦值給一個(gè)變量,把這個(gè)JSON對(duì)象保存起來(lái)進(jìn)行調(diào)用了!

var test=({
? ?"username":"zhangsan"
});
console.log(test.username);

如圖

所以{..}這種對(duì)象寫(xiě)法形式,不加外層的小括號(hào),會(huì)被識(shí)別為JS代碼塊開(kāi)始結(jié)束標(biāo)記


注意

那這個(gè)時(shí)候可能就有人要問(wèn)了, 為什么我不加這個(gè)小括號(hào)()也可以正常執(zhí)行這個(gè)JSON對(duì)象呢?

代碼如下

var test={"username":"zhangsan"};
console.log(test.username);

如圖

分析解釋

對(duì),根據(jù)JSON的語(yǔ)法定義上來(lái)說(shuō)這是沒(méi)錯(cuò), 并且你也把這一個(gè)整體賦值給了一個(gè)變量進(jìn)行保存!

這跟加一個(gè)小括號(hào)() 一個(gè)道理, 明白了吧! ?JS引擎沒(méi)有單一的把這{...}中的內(nèi)容看成是一個(gè)語(yǔ)句塊

而是把這一堆東西,賦值給了一個(gè)變量成為整體!



eval()函數(shù)使用心得體會(huì)

到這里你再次去理解eval()函數(shù)在處理字符串的時(shí)候,里面還要加一個(gè)小括號(hào)是不是就清晰很多了!

eval()函數(shù)只能接受JS代碼作為參數(shù),而不能接受JSON格式字符串作為參數(shù)

因此,當(dāng)你將一個(gè)JSON格式的字符串傳遞給eval()函數(shù)時(shí),它會(huì)拋出語(yǔ)法錯(cuò)誤

eval()函數(shù)不是你想傳遞一個(gè)字符串就一定能給你正確的進(jìn)行解析成可執(zhí)行的代碼!

需要你去觀察你傳遞的字符串信息是否合理合法, 這也很好的解釋了w3c文檔中提到的不是合法的表達(dá)式和語(yǔ)句傳遞給eval()函數(shù)是會(huì)報(bào)錯(cuò)的!

w3c文檔上其實(shí)也有明確的規(guī)定, 在處理JSON字符串的時(shí)候,最好要寫(xiě)成以下方式:

代碼如下

eval('('+jsondata+')');

這樣寫(xiě)的目的是為了讓代碼更加清晰,更容易理解!

如圖


舉個(gè)栗子

我們假設(shè)一個(gè)JSON字符串數(shù)據(jù)如下:

var data ='{"username":"張三","age":"20","company":"阿里巴巴"}';
eval(data);

這里直接使用eval()函數(shù)解析這個(gè)JSON字符串顯然不能直接解析成JSON對(duì)象, 因?yàn)閯倓偵厦嫖艺f(shuō)過(guò)了,這里很明顯把這個(gè)JSON字符串解析成了JS語(yǔ)句塊,直接報(bào)錯(cuò)!

如圖

那么我們可以給這個(gè)JSON字符串直接加上一個(gè)小括號(hào)()看看

代碼如下

var data ='({"username":"張三","age":"20","company":"阿里巴巴"})';
var result=eval(data);
console.log(typeof result);
console.log(result);

如圖

這里就是用了小括號(hào)()JS引擎把這一堆字符串當(dāng)成一個(gè)整體來(lái)看待!

也就是我們?cè)?code>JSON字符串的兩端添加括號(hào),就可以將其轉(zhuǎn)換為一個(gè)整體的JavaScript表達(dá)式

并將結(jié)果存儲(chǔ)在變量中?,F(xiàn)在這個(gè)變量是一個(gè)JS對(duì)象,我們可以使用它來(lái)訪問(wèn)JSON數(shù)據(jù)的屬性了!

如果當(dāng)你不加括號(hào)的時(shí)候的時(shí)候{}會(huì)被解釋成一個(gè)復(fù)合語(yǔ)句塊

所以你經(jīng)??赡軙?huì)見(jiàn)到在使用eval()函數(shù)解析JSON字符串的時(shí)候會(huì)寫(xiě)成eval('('+json+')');這個(gè)樣子

擴(kuò)展

其實(shí)也不用那么麻煩, 直接使用JSON.parse()函數(shù)就可以解決這個(gè)問(wèn)題了,要解析JSON字符串直接就用這個(gè),最方便!

var data ='{"username":"張三","age":"20","company":"阿里巴巴"}';
var result=JSON.parse(data);
console.log(typeof result);
console.log(result);

效果跟上面是一樣的!



eval()函數(shù)應(yīng)用場(chǎng)景

我們可能經(jīng)常會(huì)在ajax提取后端數(shù)據(jù)的時(shí)候,會(huì)獲取到一個(gè)json數(shù)據(jù),那么可能這個(gè)json數(shù)據(jù)是一個(gè)字符串,

當(dāng)你拿到之后不能直接使用, 如果直接使用eval()函數(shù)就會(huì)報(bào)錯(cuò)或者打印不出數(shù)據(jù)返回出undefined等等結(jié)果!

所以要再eval()函數(shù)里面加一個(gè)小括號(hào)

如圖



大家的支持就是我堅(jiān)持的動(dòng)力!

如果文章對(duì)你有幫助的話就請(qǐng)

??點(diǎn)贊 ??評(píng)論 ??收藏

一鍵三連哦!

??????????

如果以上內(nèi)容有任何錯(cuò)誤或者不準(zhǔn)確的地方,????歡迎在下面 ?? 留個(gè)言指出!

或者你有更好的想法,歡迎一起交流學(xué)習(xí)????????????


【趣味JavaScript】我的天! 居然工作了5年的前端開(kāi)發(fā)都不知道eval函數(shù)其中暗藏玄機(jī)!的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
尉氏县| 额敏县| 万年县| 泽州县| 玉林市| 漯河市| 甘洛县| 东乡族自治县| 上林县| 汤阴县| 宜兴市| 孟连| 洞口县| 本溪市| 南京市| 马公市| 珠海市| 大安市| 交口县| 澜沧| 鹰潭市| 兴国县| 滦平县| 开远市| 喜德县| 门源| 娱乐| 比如县| 兴隆县| 罗甸县| 清河县| 溆浦县| 中阳县| 大荔县| 霍山县| 贺州市| 皋兰县| 金坛市| 石屏县| 河曲县| 清丰县|