淺析JavaScript中嚴(yán)格模式的使用
認(rèn)識(shí)嚴(yán)格模式
在ECMAScript5標(biāo)準(zhǔn)中,JavaScript提出了嚴(yán)格模式的概念(Strict Mode):
嚴(yán)格模式很好理解,是一種具有限制性的JavaScript模式,從而是代碼隱式的脫離了“懶散(sloppy)模式”;
支持嚴(yán)格模式的瀏覽器在檢測(cè)到代碼有嚴(yán)格模式時(shí),會(huì)以更加嚴(yán)格的方式對(duì)代碼進(jìn)行檢測(cè)和執(zhí)行;
嚴(yán)格模式對(duì)正常的JavaScript語(yǔ)義進(jìn)行了一些限制:
嚴(yán)格模式通過(guò)拋出錯(cuò)誤來(lái)消除一些原有的靜默(silent)錯(cuò)誤;
嚴(yán)格模式讓JS引擎在執(zhí)行代碼時(shí)可以進(jìn)行更多的優(yōu)化(不需要對(duì)一些特殊的語(yǔ)法進(jìn)行處理);
嚴(yán)格模式禁用了在ECMAScript未來(lái)版本中可能會(huì)定義的一些語(yǔ)法(保留字等);
嚴(yán)格模式限制
JavaScript被設(shè)計(jì)為新手開(kāi)發(fā)者更容易上手,所以有時(shí)候本來(lái)語(yǔ)法錯(cuò)誤,被認(rèn)為也是可以正常被解析的;但是這種方式可能帶來(lái)留下安全隱患;在嚴(yán)格模式下,這種失誤就會(huì)被當(dāng)作錯(cuò)誤,以便可以快速的發(fā)現(xiàn)和修正
這里列一些相對(duì)比較常見(jiàn)的幾個(gè)嚴(yán)格模式下的嚴(yán)格語(yǔ)法限制:
1. 無(wú)法意外的創(chuàng)建全局變量
什么是意外的創(chuàng)建變量?看下面這段兒代碼:
message = 'Hello World' console.log(message) function foo() { age = 18 } foo() console.log(age)
這是非嚴(yán)格模式下,都是可以打印出來(lái)的,嚴(yán)格來(lái)講這種就是錯(cuò)誤語(yǔ)法,我都沒(méi)定義message和age,為什么能直接賦值。這就是意外創(chuàng)建了變量,這在嚴(yán)格模式下是不允許的:開(kāi)啟嚴(yán)格模式只需要在添加 “use strict” 就可以了,如下:
"use strict" message = 'Hello World' console.log(message) function foo() { age = 18 } foo() console.log(age)
加上之后,再運(yùn)行就會(huì)報(bào)錯(cuò)了:
2. 不允許函數(shù)有相同的參數(shù)名稱
function foo(x, y, x) { console.log(x, y, x) } foo(10, 20, 30)
上面是非嚴(yán)格模式下,是可以正常執(zhí)行的,且會(huì)打印 30 20 30,后面的x會(huì)把前面的x覆蓋掉。但是在嚴(yán)格模式下是會(huì)拋出錯(cuò)誤的,如下:
"use strict" function foo(x, y, x) { console.log(x, y, x) } foo(10, 20, 30)
這是嚴(yán)格模式,執(zhí)行報(bào)錯(cuò)如下:
3. 嚴(yán)格模式下會(huì)使引起靜默失效(silently fail:不報(bào)錯(cuò)也沒(méi)有任何效果)的賦值操作拋出異常
看下下面代碼示例:
true.name = '哈哈哈' NaN = '124' console.log(true.name) console.log(NaN)
這是非嚴(yán)格模式下,我們給布爾值添加name屬性,對(duì)NaN進(jìn)行賦值操作,當(dāng)然平時(shí)開(kāi)發(fā)中是不太可能寫這種代碼的,我們看下打印結(jié)果:
可以看到代碼可以正常執(zhí)行,且進(jìn)行了打印,但我們代碼種的賦值操作并沒(méi)有任何效果
但是在嚴(yán)格模式下是不允許有這種操作的:
"use strict" true.name = '哈哈哈' NaN = '124' console.log(true.name) console.log(NaN)
直接報(bào)錯(cuò):
4. 嚴(yán)格模式下視圖刪除不可刪除的屬性,或者視圖修改不可修改的屬性
測(cè)試代碼如下(非嚴(yán)格模式):
var obj = {} Object.defineProperty(obj, 'name', { configurable: false, writable: false, value: 'wft' }) obj.name = '小王' console.log(obj.name) delete obj.name console.log(obj.name)
看下控制臺(tái):
我們上面指定了obj中的name屬性不可修改的,也不可刪除的,但是我們嘗試對(duì)其賦值、刪除操作,發(fā)現(xiàn)運(yùn)行并無(wú)報(bào)錯(cuò),只不過(guò)是我們的操作并沒(méi)有任何效果,但是在嚴(yán)格模式下會(huì)直接報(bào)錯(cuò):
"use strict" var obj = {} Object.defineProperty(obj, 'name', { configurable: false, writable: false, value: 'wft' }) obj.name = '小王' console.log(obj.name) delete obj.name console.log(obj.name)
運(yùn)行 報(bào)錯(cuò)如下:
5. 不允許0的八進(jìn)制語(yǔ)法
在非嚴(yán)格模式下,我們可以使用 0123 來(lái)設(shè)置八進(jìn)制的
"use strict" // 不允許使用原先的八進(jìn)制格式 0123 var num8 = 0o123 // 八進(jìn)制 var num16 = 0x123 // 十六進(jìn)制 var num2 = 0b100 // 二進(jìn)制 console.log(num8, num16, num2) // 83 291 4
6. 嚴(yán)格模式下,不允許使用with語(yǔ)句
說(shuō)起with語(yǔ)句大多數(shù)小伙伴可能對(duì)這個(gè)不太熟悉啊,其實(shí)就是個(gè)語(yǔ)句,它可以有自己獨(dú)立的作用域,我們平時(shí)在函數(shù)中用到一個(gè)變量時(shí),會(huì)現(xiàn)在自己的作用域中找,找不到會(huì)接上去上層作用域找,直到找不到,但是使用了with語(yǔ)句,它不會(huì)像上層找了,直接就找自己的作用域,什么意思呢,看下面代碼:
let obj = { name: 'WFT' } function foo() { const name = '小王' function bar() { with(obj) { console.log(name) // WFT } } bar() } foo()
然后這是非嚴(yán)格模式,with中的obj可不是形參哦! 會(huì)發(fā)現(xiàn)打印出來(lái)的name是‘WFT’,而不是‘小王’ ,可以理解為他把obj結(jié)構(gòu)了,在with語(yǔ)句中可以直接訪問(wèn)其中的屬性,上面例子中作用域就是直接會(huì)去obj中找name屬性了,而不會(huì)去上層找foo中的name屬性,這個(gè)也做個(gè)了解就好了,真是開(kāi)發(fā)基本不會(huì)使用這個(gè)with語(yǔ)句的,況且這個(gè)在嚴(yán)格模式下是不允許使用with語(yǔ)句的:
嚴(yán)格模式(在編輯器中這么寫with下面直接會(huì)有波浪線提示不允許這么寫的):
"use strict" let obj = { name: 'WFT' } function foo() { const name = '小王' function bar() { with(obj) { console.log(name) // WFT } } bar() } foo()
運(yùn)行代碼也是直接報(bào)錯(cuò):
7. 嚴(yán)格模式下,eval不再為上層引用變量
eval也是js中的一個(gè)自帶的函數(shù),可以直接調(diào)用 ,可以傳入一個(gè)字符串,如果是js語(yǔ)句的話,它會(huì)直接執(zhí)行這段兒代碼,當(dāng)然平時(shí)開(kāi)發(fā)也不建議去使用它
非嚴(yán)格模式示例代碼:
var jsString = 'var message = "Hello World"; console.log(message)' eval(jsString) console.log(message)
我們可以看到控制臺(tái)會(huì)打印兩次的,下面的console.log也會(huì)打印出message的
但是在嚴(yán)格模式下,只會(huì)打印eval中的語(yǔ)句 ,不再為上層引用變量
"use strict" var jsString = 'var message = "Hello World"; console.log(message)' eval(jsString) console.log(message)
控制臺(tái):
8. 嚴(yán)格模式下,this綁定不會(huì)默認(rèn)轉(zhuǎn)成對(duì)象(this指向有點(diǎn)兒區(qū)別)
看下下面的代碼示例:
"use strict" // 在嚴(yán)格模式下,自執(zhí)行函數(shù)會(huì)指向undefined // 在非嚴(yán)格模式下,自執(zhí)行函數(shù) this會(huì)直接去引用window function foo() { console.log(this) } var obj = { name: 'wft', foo: foo } foo() obj.foo() // 這樣調(diào)用的話和非嚴(yán)格模式是一樣的 都是會(huì)指向調(diào)用者 obj var bar = obj.foo bar()
控制臺(tái)打印:
還有一種是 call apply調(diào)用函數(shù)的時(shí)候,如果在非嚴(yán)格模式下,我們第一個(gè)參數(shù)傳遞個(gè)null,或者undefined,this都會(huì)指向window的,但是在嚴(yán)格模式下,我們傳入什么this就會(huì)指向什么,傳入null,this就指向null,傳入undefined,this就指向undefined。
"use strict" function foo() { console.log(this) } foo.call(null) // null foo.apply(null) // null foo.call(undefined) // undefined foo.apply(undefined) // undefined
到此這篇關(guān)于淺析JavaScript中嚴(yán)格模式的使用的文章就介紹到這了,更多相關(guān)JavaScript嚴(yán)格模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用JavaScript實(shí)現(xiàn)圖片的自動(dòng)輪播
在網(wǎng)站開(kāi)發(fā)中,經(jīng)常會(huì)遇到需要展示多張圖片并自動(dòng)切換的需求,這就需要使用JavaScript來(lái)實(shí)現(xiàn)圖片的自動(dòng)輪播功能,本文將通過(guò)一個(gè)簡(jiǎn)單的例子,演示如何用JavaScript實(shí)現(xiàn)圖片的自動(dòng)輪播,感興趣的同學(xué)可以自己動(dòng)手試一試2023-09-09通過(guò)實(shí)例了解Javascript柯里化流程
這篇文章主要介紹了通過(guò)實(shí)例了解Javascript柯里化流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03解決JS組件bootstrap table分頁(yè)實(shí)現(xiàn)過(guò)程中遇到的問(wèn)題
這篇文章主要介紹了JS組件bootstrap table分頁(yè)實(shí)現(xiàn)過(guò)程中遇到的問(wèn)題,感興趣的小伙伴們可以參考一下2016-04-04JS中隊(duì)列和雙端隊(duì)列實(shí)現(xiàn)及應(yīng)用詳解
這篇文章主要介紹了JS中隊(duì)列和雙端隊(duì)列實(shí)現(xiàn)及應(yīng)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09