066_严格模式
1. "use strict"指令
1.1. "use strict"是JavaScript 1.8.5中的新指令(ECMAScript version 5)。
1.2. 它不算一條語句, 而是一段文字表達式, 更早版本的JavaScript會忽略它。
1.3. "use strict";的作用是指示JavaScript代碼應該以"嚴格模式"執行。
1.4. 以下版本的瀏覽器支持嚴格模式:
- 版本10以后的IE
- 版本4以后的Firefox
- 版本13以后的Chrome
- 版本5.1以后的Safari
2. 聲明嚴格模式
2.1. 通過在腳本或函數的開頭添加"use strict";來聲明嚴格模式。
2.2. 在腳本開頭進行聲明, 擁有全局作用域(腳本中的所有代碼均以嚴格模式來執行):
<script type="text/javascript">"use strict";function myFn1(){document.write(this + '<br />');}myFn1(); </script>2.3. 同一頁面中多個腳本, 可以是默認模式, 也可以是嚴格模式, 互不影響:
<script type="text/javascript">"use strict";function myFn1(){document.write(this + '<br />');}myFn1(); </script><script type="text/javascript">function myFn2(){document.write(this + '<br />');}myFn2(); </script>2.4. 在函數中聲明嚴格模式, 擁有局部作用域(只有函數中的代碼以嚴格模式執行):
function myFn3(){"use strict";document.write(this + '<br />'); } myFn3();2.5. "use strict"指令只能在腳本或函數的開頭被識別。
3. 為什么使用嚴格模式?
3.1. 嚴格模式使我們更容易編寫"安全的"JavaScript。
3.2. 嚴格模式把之前可接受的"壞語法"轉變為真實的錯誤。
4. 嚴格模式中不允許的事項
4.1. 在不聲明變量的情況下使用變量, 是不允許的:
<script type="text/javascript">"use strict";// 報錯, 嚴格模式中, 在不聲明變量的情況下使用變量, 是不允許的a = 5; </script><script type="text/javascript">// 默認模式中, 在不聲明變量的情況下使用變量, 成為全局變量b = 10; </script>4.2. 使用delete刪除變量是不允許的:
<script type="text/javascript">"use strict"; var c = 15;// 報錯, 嚴格模式中, 使用delete刪除變量, 是不允許的delete c; </script><script type="text/javascript">var d = 20;// 默認模式中, 使用delete刪除變量, 沒有任何影響delete d;document.write('d = ' + d + '<br />'); </script>4.3. 使用delete刪除函數是不允許的:
<script type="text/javascript">"use strict"; function myFn1(){document.write(this + '<br />');}// 報錯, 嚴格模式中, 使用delete刪除函數, 是不允許的delete myFn1; </script><script type="text/javascript">function myFn2(){document.write(this + '<br />');}// 默認模式中, 使用delete刪除函數, 沒有任何影響delete myFn2;myFn2(); </script>4.4 重復使用參數名, 是不允許的:
<script type="text/javascript">"use strict"; // 報錯, 嚴格模式中, 重復使用參數名, 是不允許的function myFn4(p1, p1){document.write('p1 = ' + p1 + ', p1 = ' + p1 + '<br />');}myFn4(25, 30); </script><script type="text/javascript">// 默認模式中, 重復使用參數名, 參數值是最后一個實參的值function myFn5(p1, p1){document.write('p1 = ' + p1 + ', p1 = ' + p1 + '<br />');}myFn5(35, 40); </script>4.5. 八進制數值是不允許的:
<script type="text/javascript">"use strict";// 報錯, 嚴格模式中, 八進制數值是不允許的document.write('e = ' + 010 + '<br />'); </script><script type="text/javascript">// 默認模式中, 八進制數值是允許的document.write('f = ' + 020 + '<br />'); </script>4.6. 八進制轉義字符是不允許的:
<script type="text/javascript">"use strict";// 報錯, 嚴格模式中, 八進制轉義字符是不允許的:document.write('\077' + '<br />'); </script><script type="text/javascript">// 默認模式中, 八進制轉義字符是允許的document.write('\077' + '<br />'); </script>4.7. 寫入只讀屬性是不允許的:
<script type="text/javascript">"use strict";var obj1 = {get Id(){return this.id;}};Object.defineProperty(obj1, 'id', {value: 1001, writable: false});// 報錯, 嚴格模式中, 寫入只讀屬性是不允許的obj1.id = 1002;document.write('obj1.id = ' + obj1.id + '<br />'); </script><script type="text/javascript">var obj2 = {get Id(){return this.id;}};Object.defineProperty(obj2, 'id', {value: 10001, writable: false});// 默認模式中, 寫入只讀屬性, 不會報錯, 但也不會賦值obj2.id = 10002;document.write('obj2.id = ' + obj2.id + '<br />'); </script>4.8. 寫入只能獲取的屬性是不允許的:
<script type="text/javascript">"use strict";var obj1 = {get Id(){return this.id;}};Object.defineProperty(obj1, 'id', {value: 1001, writable: false});// 報錯, 嚴格模式中, 寫入只能獲取的屬性是不允許的obj1.Id = 1003;document.write('obj1.Id = ' + obj1.Id + '<br />'); </script><script type="text/javascript">var obj2 = {get Id(){return this.id;}};Object.defineProperty(obj2, 'id', {value: 10001, writable: false});// 默認模式中, 寫入只能獲取的屬性, 不會報錯, 但也不會賦值obj2.Id = 10003;document.write('obj2.Id = ' + obj2.Id + '<br />'); </script>4.9. 刪除不可刪除的屬性是不允許的:
<script type="text/javascript">"use strict";// 報錯, 嚴格模式中, 刪除不可刪除的屬性是不允許的delete Object.prototype; </script><script type="text/javascript">// 默認模式中, 刪除不可刪除的屬性, 沒有任何影響delete Object.prototype;document.write('Object.prototype = ' + Object.prototype + '<br />'); </script>4.10. 處于安全考慮, eval()在其被調用的作用域中創建的變量, 在其它作用域中不允許:
<script type="text/javascript">"use strict";eval("var drink1 = '紅茶';document.write('drink1 = ' + drink1 + '<br />');");// 報錯, 嚴格模式中, eval()在其被調用的作用域中創建的變量, 在其它作用域中不允許document.write('drink1 = ' + drink1 + ', window.drink1 = ' + window.drink1 + '<br />'); </script><script type="text/javascript">eval("var drink2 = '綠茶';document.write('drink2 = ' + drink2 + '<br />');");// 默認模式中, eval()在其被調用的作用域中創建的變量, 在其它作用域中可以訪問, 而且它是全局變量document.write('drink2 = ' + drink2 + ', window.drink2 = ' + window.drink2 + '<br />'); </script>4.11. 字符串"eval"不可用作變量:
<script type="text/javascript">"use strict";// 報錯, 嚴格模式中, 字符串"eval"不可用作變量var eval = 'eval'; </script><script type="text/javascript">// 默認模式中, 字符串"eval"可以用作變量var eval = 'eval';document.write('eval = ' + eval + '<br />'); </script>4.12. 字符串"arguments"不可用作變量:
<script type="text/javascript">"use strict";// 報錯, 嚴格模式中, 字符串"arguments"不可用作變量var arguments = 'arguments'; </script><script type="text/javascript">// 默認模式中, 字符串"arguments"可以用作變量var arguments = 'arguments';document.write('arguments = ' + arguments + '<br />'); </script>4.13. with語句是不允許的:
<script type="text/javascript">"use strict";var book1 = "Effective Java";// 報錯, 嚴格模式中, with語句是不允許的with(book1) {document.write('book1 = ' + toUpperCase() + '<br />');} </script><script type="text/javascript">var book2 = "Netty In Action";// 默認模式中, with語句是允許的with(book2) {document.write('book2 = ' + toUpperCase() + '<br />');} </script>5. 對未來的保障
5.1. 嚴格模式中不允許使用為未來預留的關鍵詞。它們是:
implements interface let package private protected public static yield6. 函數中的this(嚴格模式)
6.1. JavaScript嚴格模式不允許默認綁定。
6.2. 因此, 在函數中使用時, 在嚴格模式下, this是未定義的undefined。
<script type="text/javascript">"use strict";function myFn6(){document.write(this + '<br />'); // 輸出undefined}myFn6(); </script>7. 函數中的this(默認)
7.1. 在JavaScript函數中, 函數的擁有者默認綁定this。
7.2. 因此, 在函數中, this指的是全局對象[object Window]。
<script type="text/javascript">function myFn7(){document.write(this + '<br />'); // 輸出[object Window]}myFn7(); </script>8. 例子
8.1. 代碼
<!DOCTYPE html> <html><head><meta charset="utf-8" /><title>嚴格模式</title></head><body><script type="text/javascript">"use strict";function myFn1(){document.write(this + '<br />');}myFn1();// 報錯, 嚴格模式中, 在不聲明變量的情況下使用變量, 是不允許的// a = 5;var c = 15;// 報錯, 嚴格模式中, 使用delete刪除變量, 是不允許的// delete c;// 報錯, 嚴格模式中, 使用delete刪除函數, 是不允許的// delete myFn1;// 報錯, 嚴格模式中, 重復使用參數名, 是不允許的// function myFn4(p1, p1){// document.write('p1 = ' + p1 + ', p1 = ' + p1 + '<br />');// }// myFn4(25, 30);// 報錯, 嚴格模式中, 八進制數值是不允許的// document.write('e = ' + 010 + '<br />');// 報錯, 嚴格模式中, 八進制轉義字符是不允許的:// document.write('\077' + '<br />');var obj1 = {get Id(){return this.id;}};Object.defineProperty(obj1, 'id', {value: 1001, writable: false});// 報錯, 嚴格模式中, 寫入只讀屬性是不允許的// obj1.id = 1002;document.write('obj1.id = ' + obj1.id + '<br />');// 報錯, 嚴格模式中, 寫入只能獲取的屬性是不允許的// obj1.Id = 1003;document.write('obj1.Id = ' + obj1.Id + '<br />');// 報錯, 嚴格模式中, 刪除不可刪除的屬性是不允許的// delete Object.prototype;eval("var drink1 = '紅茶';document.write('drink1 = ' + drink1 + '<br />');");// 報錯, 嚴格模式中, eval()在其被調用的作用域中創建的變量, 在其它作用域中不允許// document.write('drink1 = ' + drink1 + ', window.drink1 = ' + window.drink1 + '<br />');// 報錯, 嚴格模式中, 字符串"eval"不可用作變量// var eval = 'eval';// 報錯, 嚴格模式中, 字符串"arguments"不可用作變量// var arguments = 'arguments';var book1 = "Effective Java";// 報錯, 嚴格模式中, with語句是不允許的// with(book1) {// document.write('book1 = ' + toUpperCase() + '<br />');// }function myFn6(){document.write(this + '<br />'); // 輸出undefined}myFn6();</script><script type="text/javascript">function myFn2(){document.write(this + '<br />');}myFn2();function myFn3(){"use strict";document.write(this + '<br />');}myFn3();// 默認模式中, 在不聲明變量的情況下使用變量, 成為全局變量b = 10;var d = 20;// 默認模式中, 使用delete刪除變量, 沒有任何影響delete d;document.write('d = ' + d + '<br />');// 默認模式中, 使用delete刪除函數, 沒有任何影響delete myFn2;myFn2();// 默認模式中, 重復使用參數名, 參數值是最后一個實參的值function myFn5(p1, p1){document.write('p1 = ' + p1 + ', p1 = ' + p1 + '<br />');}myFn5(35, 40);// 默認模式中, 八進制數值是允許的document.write('f = ' + 020 + '<br />');// 默認模式中, 八進制轉義字符是允許的document.write('\077' + '<br />');var obj2 = {get Id(){return this.id;}};Object.defineProperty(obj2, 'id', {value: 10001, writable: false});// 默認模式中, 寫入只讀屬性, 不會報錯, 但也不會賦值obj2.id = 10002;document.write('obj2.id = ' + obj2.id + '<br />');// 默認模式中, 寫入只能獲取的屬性, 不會報錯, 但也不會賦值obj2.Id = 10003;document.write('obj2.Id = ' + obj2.Id + '<br />');// 默認模式中, 刪除不可刪除的屬性, 沒有任何影響delete Object.prototype;document.write('Object.prototype = ' + Object.prototype + '<br />');eval("var drink2 = '綠茶';document.write('drink2 = ' + drink2 + '<br />');");// 默認模式中, eval()在其被調用的作用域中創建的變量, 在其它作用域中可以訪問, 而且它是全局變量document.write('drink2 = ' + drink2 + ', window.drink2 = ' + window.drink2 + '<br />');// 默認模式中, 字符串"eval"可以用作變量var eval = 'eval';document.write('eval = ' + eval + '<br />');// 默認模式中, 字符串"arguments"可以用作變量var arguments = 'arguments';document.write('arguments = ' + arguments + '<br />');var book2 = "Netty In Action";// 默認模式中, with語句是允許的with(book2) {document.write('book2 = ' + toUpperCase() + '<br />');}function myFn7(){document.write(this + '<br />'); // 輸出[object Window]}myFn7();</script></body> </html>8.2. 效果圖
總結
 
                            
                        - 上一篇: 065_const关键字
- 下一篇: 067_this关键字
