<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # 嚴格模式 ECMAScript 5的嚴格模式是采用具有限制性JavaScript變體的一種方式,從而使代碼顯示地 脫離“馬虎模式/稀松模式/懶散模式“(sloppy)模式。 * 嚴格模式通過拋出錯誤來消除了一些原有靜默錯誤。 * 嚴格模式修復了一些導致 JavaScript引擎難以執行優化的缺陷:有時候,相同的代碼,嚴格模式可以比非嚴格模式下運行得更快。 * 嚴格模式禁用了在ECMAScript的未來版本中可能會定義的一些語法。 ## 調用嚴格模式 ### 為腳本開啟嚴格模式 為整個腳本文件開啟嚴格模式,需要在所有語句之前放一個特定語句 `"use strict"`; (或 'use strict';) ``` // 整個腳本都開啟嚴格模式的語法 "use strict"; var v = "Hi! I'm a strict mode script!"; ``` <br> ### 為函數開啟嚴格模式 同樣的,要給某個函數開啟嚴格模式,得把 `"use strict"; (或 'use strict'; )`聲明一字不漏地放在函數體所有語句之前。 ``` function strict(){ // 函數級別嚴格模式語法 'use strict'; function nested() { return "And so am I!"; } return "Hi! I'm a strict mode function! " + nested(); } function notStrict() { return "I'm not strict."; } ``` <br> ## 無法再意外創建全局變量 ``` // 無法再意外創建全局變量 // Uncaught ReferenceError: mistypedVaraible is not defined mistypedVaraible = 17; ``` <br> ## 會使引起靜默失敗 即不報錯也沒有任何效果。任何在正常模式下引起靜默失敗的賦值操作 (給不可寫屬性賦值, 給只讀屬性(getter-only)賦值賦值, 給不可擴展對象(non-extensible object)的新屬性賦值) 都會拋出異常。 ``` // 給不可寫的全局變量賦值 var NaN = 1 // TypeError: Cannot assign to read only property 'NaN' of object '#<Window>' // 給不可寫屬性賦值 var obj1 = {}; Object.defineProperty(obj1, "x", { value: 42, writable: false }); obj1.x = 9; // TypeError: Cannot assign to read only property 'x' of object '#<Object>' // 給只讀屬性賦值 var obj2 = { get x() { return 17; } }; obj2.x = 5; // TypeError: Cannot set property x of #<Object> which has only a getter // 給不可擴展對象的新屬性賦值 var fixed = {}; Object.preventExtensions(fixed); fixed.newProp = "ohai"; // TypeError: Cannot add property newProp, object is not extensible ``` <br> ## 刪除不可刪除的屬性 ``` delete Object.prototype // TypeError: Cannot delete property 'prototype' of function Object() { [native code] } ``` ## 一個對象內的所有屬性名在對象內必須唯一(Chrome無效) ``` "use strict"; var o = { p: 1, p: 2 }; // !!! 語法錯誤 ``` <br> ## 函數的參數名唯一 在正常模式下, 最后一個重名參數名會掩蓋之前的重名參數. 之前的參數仍然可以通過 `arguments[i]` 來訪問, 還不是完全無法訪問. 然而, 這種隱藏毫無意義而且可能是意料之外的 ``` function sum(a, a, c){ // !!! 語法錯誤 "use strict"; return a + a + c; // SyntaxError: Duplicate parameter name not allowed in this context } ``` <br> ## 禁止八進制數字語法 ECMAScript并不包含八進制語法, 但所有的瀏覽器都支持這種以零(0)開頭的八進制語法: `0644 === 420` 還有 `"\045" === "%"`.在ECMAScript 6中支持為一個數字加"0o"的前綴來表示八進制數 ``` var a = 0o10; // ES6: 八進制 ``` <br> 有些新手開發者認為數字的前導零沒有語法意義, 所以他們會用作對齊措施 — 但其實這會改變數字的意義! 八進制語法很少有用并且可能會錯誤使用, 所以嚴格模式下八進制語法會引起語法錯誤: ``` "use strict"; var sum = 015 + 197 + 142; // SyntaxError: Octal literals are not allowed in strict mode. ``` <br> ## 禁止設置基本類型的屬性 ``` false.true = ""; // TypeError: Cannot create property 'true' on boolean 'false' (14).sailing = "home"; // TypeError: Cannot create property 'sailing' on number '14' "with".you = "far away"; // TypeError: Cannot create property 'you' on string 'with' ``` <br> ## 禁用 with with所引起的問題是塊內的任何名稱可以映射(map)到with傳進來的對象的屬性, 也可以映射到包圍這個塊的作用域內的變量(甚至是全局變量), 這一切都是在運行時決定的: 在代碼運行之前是無法得知的。 <br> 一種取代 with的簡單方法是,將目標對象賦給一個短命名變量,然后訪問這個變量上的相應屬性 <br> ## eval 不再為上層范圍引入新變量 在正常模式下, 代碼 eval("var x;") 會給上層函數(surrounding function)或者全局引入一個新的變量 x . 這意味著, 一般情況下, 在一個包含 eval 調用的函數內所有沒有引用到參數或者局部變量的名稱都必須在運行時才能被映射到特定的定義 (因為 eval 可能引入的新變量會覆蓋它的外層變量). 在嚴格模式下 eval 僅僅為被運行的代碼創建變量, 所以 eval 不會使得名稱映射到外部變量或者其他局部變量 ``` var x = 17; var evalX = eval("'use strict'; var x = 42; x"); console.assert(x === 17); console.assert(evalX === 42); ``` <br> ## 禁止刪除聲明變量 ``` var x; delete x; // SyntaxError: Delete of an unqualified identifier in strict mode ``` <br> ## 名稱 eval 和 arguments 不能通過程序語法被綁定或賦值 以下的所有嘗試將引起語法錯誤 ``` eval = 17; arguments++; ++eval; var obj = { set p(arguments) { } }; var eval; try { } catch (arguments) { } function x(eval) { } function arguments() { } var y = function eval() { }; var f = new Function("arguments", "'use strict'; return 17;"); ``` ## 參數的值不會隨 arguments 對象的值的改變而變化 正常模式下,對于第一個參數是 arg 的函數,對 arg 賦值時會同時賦值給 `arguments[0]`,反之亦然(除非沒有參數,或者 `arguments[0]` 被刪除)。 嚴格模式下,函數的 arguments 對象會保存函數被調用時的原始參數。`arguments[i]` 的值不會隨與之相應的參數的值的改變而變化,同名參數的值也不會隨與之相應的 `arguments[i]` 的值的改變而變化。 ``` function f(a){ "use strict"; a = 42; return [a, arguments[0]]; } f(17); // [42, 17] ``` <br> ``` function f(a){ a = 42; return [a, arguments[0]]; } f(17); // [42, 42] ``` <br> ## 不再支持 arguments.callee 正常模式下,`arguments.callee` 指向當前正在執行的函數。這個作用很小:直接給執行函數命名就可以了!此外,`arguments.callee` 十分不利于優化,例如內聯函數,因為 `arguments.callee` 會依賴對非內聯函數的引用。 在嚴格模式下,`arguments.callee` 是一個不可刪除屬性,而且賦值和讀取時都會拋出異常 ``` var f2 = function() { return arguments.callee; }; f2(); // 拋出類型錯誤 ``` ## 通過this傳遞給一個函數的值不會被強制轉換為一個對象 對于一個開啟嚴格模式的函數,指定的this不再被封裝為對象,而且如果沒有指定this的話它值是undefined: ``` function fun() { return this; } fun() === undefined // false fun.call(2) === 2 // false fun.apply(null) === null // false fun.call(undefined) === undefined // false fun.bind(true)() === true // false ``` <br> ``` 'use strict' function fun() { return this; } fun() === undefined // true fun.call(2) === 2 // true fun.apply(null) === null // true fun.call(undefined) === undefined // true fun.bind(true)() === true // true ``` <br> ## 不能通過廣泛實現的ECMAScript擴展“游走于”JavaScript的棧中 在普通模式下用這些擴展的話,當一個叫fun的函數正在被調用的時候,fun.caller是最后一個調用fun的函數,而且fun.arguments包含調用fun時用的形參。這兩個擴展接口對于“安全”JavaScript而言都是有問題的,因為他們允許“安全的”代碼訪問"專有"函數和他們的(通常是沒有經過保護的)形參。 <br> 如果fun在嚴格模式下,那么fun.caller和fun.arguments都是不可刪除的屬性而且在存值、取值時都會報錯: ``` function restricted() { "use strict"; restricted.caller; // 拋出類型錯誤 restricted.arguments; // 拋出類型錯誤 } function privilegedInvoker() { return restricted(); } privilegedInvoker(); ``` <br> ## arguments不會再提供訪問與調用這個函數相關的變量的途徑 嚴格模式下的arguments不會再提供訪問與調用這個函數相關的變量的途徑。在一些舊時的ECMAScript實現中arguments.caller曾經是一個對象,里面存儲的屬性指向那個函數的變量。這是一個安全隱患,因為它通過函數抽象打破了本來被隱藏起來的保留值;它同時也是引起大量優化工作的原因。出于這些原因,現在的瀏覽器沒有實現它。但是因為它這種歷史遺留的功能,arguments.caller在嚴格模式下同樣是一個不可被刪除的屬性,在賦值或者取值時會報錯: ``` function fun(a, b) { "use strict"; var v = 12; return arguments.caller; // 拋出類型錯誤 } fun(1, 2); // 不會暴露v(或者a,或者b) ``` <br> ## 一部分字符變成了保留的關鍵字 這些字符包括implements, interface, let, package, private, protected, public, static和yield。在嚴格模式下,你不能再用這些名字作為變量名或者形參名。 ``` function package(protected){ // !!! "use strict"; var implements; // !!! interface: // !!! while (true) { break interface; // !!! } function private() { } // !!! } function fun(static) { 'use strict'; } // !!! ``` <br> ## 禁止了不在腳本或者函數層面上的函數聲明(chrome未實現) ``` "use strict"; if (true){ function f() { } // !!! 語法錯誤 f(); } for (var i = 0; i < 5; i++){ function f2() { } // !!! 語法錯誤 f2(); } function baz() { // 合法 function eit() { } // 同樣合法 } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看