摘要:整個腳本文件就會以嚴格模式執行。函數作用域范圍將放在函數體的第一行,則整個函數以嚴格模式運行。嚴格模式下,必須指明的指向對象。禁止在非函數代碼塊聲明函數的嚴格模式只允許在全局作用域或函數作用域聲明函數。
ECMAScript 5 引入了 strict mode ,現在已經被大多瀏覽器實現(從IE10開始)
一、什么是嚴格模式顧名思義,JavaScript 嚴格模式就是讓 JS 代碼以更嚴格的模式執行,不允許可能會引發錯誤的代碼執行。在正常模式下靜默失敗的代碼,嚴格模式下就會拋出錯誤。
二、為什么要過渡到嚴格模式嚴格模式下的代碼在運行的時候,更容易通過拋出的錯誤定位到問題所在的地方
嚴格模式能夠幫助你編寫更符合規范的代碼
消除 JavaScript 語言上一些不合理,比較怪異的行為
為未來新版本的 JavaScript 做鋪墊
有時候,嚴格模式下的 JavaScript 代碼運行起來更快
三、如何使用· 腳本文件范圍
將 "use strict"; 放在腳本文件的第一行。整個腳本文件就會以“嚴格模式”執行。
· 函數作用域范圍
將 "use strict"; 放在函數體的第一行,則整個函數以"嚴格模式"運行。
文件合并時,寫在腳本文件第一行的 "use strict"; 來實現嚴格模式會失效,可以將腳本文件的代碼放在一個立即執行表達式中。
(funciton() { "use strict"; ... })()四、嚴格模式的具體定義
嚴格模式下無法再隱式創建全局變量
也就是,變量必須聲明后才能使用,正常模式直接賦值給一個未定義的變量時,會將變量定義為全局變量。
"use strict"; var a = b = 3; // Uncaught ReferenceError: b is not defined 以上代碼等于: var a; b = 3; a = b;
禁止 this 關鍵字指向全局對象
正常模式下,函數中如果沒有指明 this 對象,JS 則會將 this 隱式指向為全局對象。如果綁定的值是非對象,將被自動轉為對象再綁定上去,而 null 和 undefined 這兩個無法轉成對象的值,將被忽略。
嚴格模式下,必須指明 this 的指向對象。如果沒有指明的話,this的值為 undefined
var name = "foo"; function func() { "use strict"; this.name; // Uncaught TypeError: Cannot read property "name" of undefined } func(); // 沒有加 new 關鍵字 new func(); function func() { return this } func() // window func.call(8) // Number {8} func.call(true) // Boolean {true} func.call("abcd") // {"abcd"} func.call(null) // window func.call(undefined) // window "use strict" function func() { return this } func() // undefined func.call(8) // 8 func.call(true) // true func.call(null) //null func.call(undefined) // undefined
不允許在函數內部遍歷調用棧
禁止使用 arguments.callee、arguments.caller、fn.caller、fn.callee;
在嚴格模式下,arguments.callee 是一個不可刪除屬性,而且賦值和讀取時都會拋出異常
function func() { "use strict"; func.caller; // 報錯 func.arguments; // Uncaught TypeError: "caller", "callee", and "arguments" properties may not be accessed on strict mode functions or the arguments objects for calls to them } func()
禁止向對象的只讀屬性賦值,禁止刪除對象的不可設置屬性, 禁止向不可擴展的對象添加屬性
無法刪除 var 聲明的變量。
在正常模式中,給對象的只讀屬性賦值, 刪除對象的不可設置屬性,添加不可擴展對象的新屬性,會靜默失敗。
但是在嚴格模式中,會拋出錯誤。
另外,字符串的屬性 length 也是只讀屬性,修改后會報錯。
"use strict"; var str = "abc" str.length = 8 // Uncaught TypeError: Cannot assign to read only property "length" of string "abc" "use strict"; var obj = Object.defineProperty({}, "a", { value: 37, writable: false }); obj.a = 123; // Uncaught TypeError: Cannot assign to read only property "a" of object "# "use strict"; var obj = Object.defineProperty({}, "p", { value: 37, configurable: false }); delete obj.p // Uncaught TypeError: Cannot delete property "p" of #
對象不允許有重名的屬性,函數不允許有重名的參數
在正常模式中,對象的重名屬性,位置靠后會覆蓋位置靠前的重名屬性。函數也是,函數體查找到的參數,靠后的重名參數會覆蓋靠前的重名參數。
"use strict"; var o = { p: 1, p: 2 }; // IE報錯:strict 模式下不允許一個屬性有多個定義, 新版的 Chrome 和 firefox 并不會報錯,會采用覆蓋機制。 "use strict"; function func(a, a) { console.log(a) } func(1, 2) // IE報錯: strict 模式下不允許正式參數名稱重復。新版的 Chrome 和 firefox 并不會報錯,會采用覆蓋機制。
靜態綁定
JavaScript 支持動態綁定,也就是 JavaScript 的屬性和方法是在運行時確定,而不是在編譯時確定。
于是,JavaScript 嚴格模式禁用了 with 語句, 因為使用了 with 語句,with 語句塊中變量無法確定是外部全局變量還是傳入的對象屬性。
"use strict"; var x = 17; with (obj) // !!! 語法錯誤 { // 如果沒有開啟嚴格模式,with 中的這個x會指向 with 上面的那個 x,還是obj.x? // 如果不運行代碼,我們無法知道,因此,這種代碼讓引擎無法進行優化,速度也就會變慢。 x; // Uncaught SyntaxError: Strict mode code may not include a with statement }
eval 關鍵字不再會給上層函數(surrounding function)或者全局引入一個新的變量。在嚴格模式中,eval 語句會創建自己的一個作用域,eval 里的變量只能在 eval 內部使用。
arguments 的限定
嚴格模式規定名稱為 eval 和 arguments 不能通過程序語法被綁定(be bound)或賦值
嚴格模式下,參數的值不會隨 arguments 對象的值的改變而變化。
正常模式中,對參數重新賦值,會修改 arguments 類數組對象下的參數值。同時,修改 arguments 類數組對象的值,也會修改函數參數的值。
嚴格模式下,不僅參數的值不會隨著 arguments 類數組對象的變化而變化,參數的變化也不會引起 arguments 對象的變化,arguments 對象會記住參數的傳入初始值。
function func(a) { "use strict" a = 8; // arguments[0] = 8 return [a, arguments[0]] } func(3) // [8, 3] function func(a) { "use strict" arguments[0] = 8 return [a, arguments[0]] } func(3) // [3, 8]
ES5禁止在非函數代碼塊聲明函數
ES5 的嚴格模式只允許在全局作用域或函數作用域聲明函數。也就是說,不允許在非函數的代碼塊內聲明函數。
if (true) { function add() { } } add() for (var i = 0; i < 5; i++){ function f2() { } // !!! 語法錯誤 f2(); } 以上代碼在嚴格模式是禁止的,但是在 ES6 中,是允許在代碼塊中聲明函數的。
保留關鍵字
嚴格模式中一部分字符變成了保留的關鍵字。這些字符包括implements, interface, let, package, private, protected, public, static和yield。在嚴格模式下,你不能再用這些名字作為變量名或者形參名
function private() {"use strict" } //Uncaught SyntaxError: Unexpected strict mode reserved word
嚴格模式禁止八進制數字語法
五、向嚴格模式過渡嚴格模式能夠幫助我們寫出更安全,更有規范的代碼,則應該避免一些危險的寫法,采用更好的寫法:
變量先聲明,再使用,
this 應該在指向自己創建的對象時使用。
arguments 應該在函數第一行就拷貝出來。
六、嚴格模式的缺點現在的代碼都會進行文件壓縮和合并,此時嚴格模式就會失效。
總結現在的 webpack 會在打包的時候默認是嚴格模式,所以現在不用再手動寫 use strict了。嚴格模式能幫助我們以更規范的方式書寫代碼,但是無論是否嚴格模式,都應該注意代碼的規范,避免隱式 bug 的出現。
2018/02/08 @Starbucks
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101568.html
摘要:因為在微信小程序中,和都是,加上又強制使用嚴格模式,為,掛載就會發生錯誤,所以就有人又發了一個,代碼變成了這就是現在的樣子。 前言 在 《JavaScript 專題系列》 中,我們寫了很多的功能函數,比如防抖、節流、去重、類型判斷、扁平數組、深淺拷貝、查找數組元素、通用遍歷、柯里化、函數組合、函數記憶、亂序等,可以我們該如何組織這些函數,形成自己的一個工具函數庫呢?這個時候,我們就要借...
摘要:使用或調用由于已經在詞法層面完成了綁定,通過或方法調用一個函數時,只是傳入了參數而已,對并沒有什么影響箭頭函數不會在其內部暴露出參數等等,都不會指向箭頭函數的,而是指向了箭頭函數所在作用域的一個名為的值如果有的話,否則,就是。 ES6之箭頭函數 標簽(空格分隔): 未分類 返回值 單行函數體默認返回改行計算結果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
摘要:使用或調用由于已經在詞法層面完成了綁定,通過或方法調用一個函數時,只是傳入了參數而已,對并沒有什么影響箭頭函數不會在其內部暴露出參數等等,都不會指向箭頭函數的,而是指向了箭頭函數所在作用域的一個名為的值如果有的話,否則,就是。 ES6之箭頭函數 標簽(空格分隔): 未分類 返回值 單行函數體默認返回改行計算結果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
摘要:使用或調用由于已經在詞法層面完成了綁定,通過或方法調用一個函數時,只是傳入了參數而已,對并沒有什么影響箭頭函數不會在其內部暴露出參數等等,都不會指向箭頭函數的,而是指向了箭頭函數所在作用域的一個名為的值如果有的話,否則,就是。 ES6之箭頭函數 標簽(空格分隔): 未分類 返回值 單行函數體默認返回改行計算結果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
閱讀 3384·2023-04-26 01:46
閱讀 2906·2023-04-25 20:55
閱讀 5471·2021-09-22 14:57
閱讀 2974·2021-08-27 16:23
閱讀 1712·2019-08-30 14:02
閱讀 2063·2019-08-26 13:44
閱讀 644·2019-08-26 12:08
閱讀 2951·2019-08-26 11:47