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