日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

被嫌弃的eval和with

發(fā)布時(shí)間:2023/12/2 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 被嫌弃的eval和with 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前面的話

  eval和with經(jīng)常被嫌棄,好像它們的存在就是錯(cuò)誤。在CSS中,表格被嫌棄,在網(wǎng)頁(yè)中只是用表格來(lái)展示數(shù)據(jù),而不是做布局,都可能被斥為不規(guī)范,矯枉過(guò)正。那關(guān)于eval和with到底是什么情況呢?本文將詳細(xì)介紹eval()函數(shù)和with語(yǔ)句

?

eval

定義

  eval()是一個(gè)全局函數(shù),javascript通過(guò)eval()來(lái)解釋運(yùn)行由javascript源代碼組成的字符串

var result = eval('3 2'); console.log(result,typeof result);//5 'number'

用法

  eval()只有一個(gè)參數(shù),如果傳入的參數(shù)不是字符串,它直接返回這個(gè)參數(shù)。如果參數(shù)是字符串,它會(huì)把字符串當(dāng)成javascript代碼進(jìn)行編譯。如果編譯失敗則拋出一個(gè)語(yǔ)法錯(cuò)誤(syntaxError)異常。如果編譯成功,則開始執(zhí)行這段代碼,并返回字符串中的最后一個(gè)表達(dá)式或語(yǔ)句的值,如果最后一個(gè)表達(dá)式或語(yǔ)句沒有值,則最終返回undefined。如果字符串拋出一個(gè)異常,這個(gè)異常將把該調(diào)用傳遞給eval()

var num = 1; var str = 'test'; console.log(eval(num));//1 console.log(eval(str));//ReferenceError: test is not defined var strLong1 = 'var x = 1;var y = 2;'; console.log(eval(strLong1),x,y);//undefined 1 2var strLong2 = 'var x = 1; x ;'; console.log(eval(strLong2),x);//1 2

作用域

  eval()使用了調(diào)用它的變量作用域環(huán)境。也就是說(shuō),它查找變量的值和定義新變量和函數(shù)的操作和局部作用域中的代碼完全一樣

var b = 2; function foo(str,a){eval(str);console.log(a,b); } foo('var b = 3;',1);//1 3

別名

  當(dāng)通過(guò)別名調(diào)用時(shí),eval()會(huì)將其字符串當(dāng)做頂層的全局代碼來(lái)執(zhí)行。執(zhí)行的代碼可能會(huì)定義新的全局變量和全局函數(shù),或者給全局變量賦值,但卻不能使用或修改函數(shù)中的局部變量

var geval = eval; var x = 'global',y = 'global'; function f(){var x = 'local';eval('x = "changed";');return x; } function g(){var y = 'local';geval('y = "changed";');return y; } console.log(f(),x);//localchanged global console.log(g(),y);//local globalchanged

  [注意]IE8-瀏覽器通過(guò)別名調(diào)用eval()和正常調(diào)用eval()的結(jié)果相同

副作用

  javascript解釋器進(jìn)行了大量的代碼分析和優(yōu)化。而eval()的問(wèn)題在于,用于動(dòng)態(tài)執(zhí)行的代碼通常不能分析,于是解釋器也無(wú)法對(duì)其進(jìn)行優(yōu)化,這會(huì)導(dǎo)致性能下降

  與eval()類似的有setTimeout()、setInterval()、new Function()等,這些函數(shù)都可以以字符串作為參數(shù),在程序運(yùn)行時(shí)動(dòng)態(tài)執(zhí)行。這種執(zhí)行機(jī)制帶來(lái)的好處無(wú)法抵消其性能上的損失,所以應(yīng)該盡量避免使用

嚴(yán)格模式

  由于eval()函數(shù)過(guò)于強(qiáng)大,嚴(yán)格模式對(duì)其進(jìn)行了嚴(yán)格的限制

  【1】不能通過(guò)eval()函數(shù)來(lái)創(chuàng)建變量或函數(shù),但可以查詢和更改其值

'use strict'; eval('var x = 1;'); console.log(x);//ReferenceError: x is not defined'use strict'; var x = 1; eval('x = 2;'); console.log(x);//2

  【2】禁止使用eval作為標(biāo)識(shí)符

'use strict'; var eval = 10;//SyntaxError: Unexpected eval or arguments in strict mode

?

with

  定義with語(yǔ)句的目的主要是為了簡(jiǎn)化多次編寫同一對(duì)象的工作

  with語(yǔ)句將object添加到作用域鏈的頭部,然后執(zhí)行statement,最后把作用域鏈恢復(fù)到原始狀態(tài)

with(object){statement; }

作用

  在對(duì)象嵌套層次很深的時(shí)候通常會(huì)使用with語(yǔ)句來(lái)簡(jiǎn)化代碼編寫。而本質(zhì)上是通過(guò)將一個(gè)對(duì)象的引用當(dāng)作作用域來(lái)處理,將對(duì)象的屬性當(dāng)作作用域中的標(biāo)識(shí)符來(lái)處理,從而創(chuàng)建了一個(gè)新的詞法作用域

  在客戶端javascript中,可能會(huì)使用類似下面這種表達(dá)式來(lái)訪問(wèn)一個(gè)HTML表單中的元素

document.forms[0].address.value

  如果這種表達(dá)式在代碼中多次出現(xiàn),則可以使用with語(yǔ)句將form對(duì)象添加到作用域鏈的頂層

with(document.forms[0]){name.value = '';address.value = '';emai.value = ''; }

  這種方法減少了大量的輸入,不用再為每個(gè)屬性名添加document.forms[0]前綴。這個(gè)對(duì)象臨時(shí)掛載在作用域鏈上,當(dāng)javascript需要解析諸如address的標(biāo)識(shí)符時(shí),就會(huì)自動(dòng)在這個(gè)對(duì)象中查找?

  [注意]with語(yǔ)句提供了一種讀取對(duì)象的屬性的快捷方式,但它并不能創(chuàng)建對(duì)象的屬性

  如果對(duì)象o有一個(gè)屬性x,那么下面代碼給這個(gè)屬性賦值為1

var o = {x:0}; with(o) x = 1; console.log(o.x);//1

  如果o中沒有定義屬性x,下面代碼和不使用with語(yǔ)句的代碼x=1是一模一樣的。這是因?yàn)閷?duì)變量x進(jìn)行了LHS查詢,并將1賦值給它

var o = {}; with(o) x = 1; console.log(o.x);//undefined console.log(x);//1

副作用

  與eval類似,with語(yǔ)句的javascript代碼非常難于優(yōu)化,同時(shí)也會(huì)給調(diào)試代碼造成困難,并且同沒有使用with語(yǔ)句的代碼相比,它運(yùn)算得更慢

  而且,如果with語(yǔ)句使用不當(dāng),還有可能造成變量泄漏,污染全局作用域的情況

var x = 1; var o = {}; with(o){x = 2; } console.log(x);//2 console.log(o.x);//undefined

嚴(yán)格模式

  嚴(yán)格模式下,禁止使用with語(yǔ)句

//SyntaxError: Strict mode code may not include a with statement 'use strict'; var o = {}; with(o){x = 2; }

?

最后

  使用eval和with會(huì)使得引擎無(wú)法在編譯時(shí)對(duì)作用域查找進(jìn)行優(yōu)化,從而導(dǎo)致性能下降,代碼運(yùn)行變慢。因?yàn)閑val和with在實(shí)際工作中很少使用,所以嚴(yán)格模式下的限制,對(duì)我們來(lái)說(shuō)影響不大。就像比如外交部某一天發(fā)布公告,我國(guó)不再發(fā)放去牙買加的簽證,牙買加雖然都聽過(guò),但大多數(shù)人這輩子都可能不去一回,所以,無(wú)所謂了。同樣地,eval和with被嫌棄不嫌棄的,也是無(wú)所謂了

  但即使不去牙買加,也不妨礙我了解到牙買加是加勒比海的其中一個(gè)島國(guó),它是英聯(lián)邦成員國(guó),也就是原來(lái)的英國(guó)殖民地,后來(lái)獨(dú)立了。它的國(guó)旗上面是一個(gè)X

  類比于eval和with

  以上


更多專業(yè)前端知識(shí),請(qǐng)上 【猿2048】www.mk2048.com

總結(jié)

以上是生活随笔為你收集整理的被嫌弃的eval和with的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。