1. 엄격 모드란
일반적으로 우리가 작성하는 JavaScript 코드는 일반 실행 모드 외에도 ECMAscript 5에는 "엄격 모드"라는 두 번째 실행 모드가 추가됩니다. 이름에서 알 수 있듯이 이 모드를 사용하면 JavaScript가 더욱 엄격한 환경에서 실행됩니다.
IE 10을 포함한 주요 브라우저는 이미 이를 지원하고 있으며 많은 대규모 프로젝트에서 이를 완전히 수용하기 시작했습니다. (github의 많은 프로젝트는 엄격 모드를 사용합니다)
2. 엄격 모드 활성화
전체 스크립트에 대해 엄격 모드 활성화
모든 명령문 앞에 "use strict";
라는 특정 명령문을 넣으세요.
reeoo.js 스크립트가 있다고 가정하면 다음과 같이 엄격 모드를 켤 수 있습니다.
"use strict"; var name = "Reeoo"; console.log(name);
이러한 작성 방식에는 자연스러운 함정이 있습니다. 하지만 코드를 병합하려면 이제 heigui.js를 병합하겠습니다.
heigui = "db";
reeoo.js와 병합하면 두 스크립트를 별도로 실행하는 것이 좋지만 병합하면 오류가 보고됩니다.
잡히지 않은 참조 오류: heigui가 정의되지 않았습니다(…)
엄격 모드 스크립트와 비엄격 모드 스크립트를 병합하면 비엄격 모드 스크립트 코드에서 오류가 보고될 수 있습니다. 코드를 즉시 실행 함수로 래핑하는 것이 좋습니다.
(function(){ "use strict"; var name = "reeoo"; })(); (function(){ heigui = "db"; })();
이렇게 하면 병합 후에 오류가 보고되지 않습니다.
함수에 대해 엄격 모드 활성화
함수에 대해 엄격 모드를 활성화하려면 함수 본문의 모든 문 앞에 "use strict" 문을 넣으면 됩니다.
function strictFun() { // 函数级别严格模式语法 'use strict'; console.log('I am a strictmode function!'); } function normalFun() { console.log('I am a mormal function!'); }
Chrome에서 엄격 모드 디버깅
다음 코드가 있습니다:
'use strict' name = "reeoo"; console.log(name)
이 코드를 Chrome 콘솔에 직접 붙여넣고 실행하세요. 정상적인 상황에서는 오류가 보고되어야 하지만 오류는 보고되지 않습니다.
분명히 엄격 모드에서는 var 없이 변수를 선언하는 것이 불법인데 왜 오류가 보고되지 않나요?
이게 도대체 뭐죠? Chrome은 엄격 모드를 지원하지 않나요? 정말 농담이에요. . .
온라인으로 검색한 결과 Chrome의 콘솔 코드는 eval에서 실행되며 eval 함수에 엄격 모드를 사용할 수 없는 것으로 나타났습니다(완전히 정확하지 않을 수 있지만 Chrome이 정확히 무엇을 하는지는 알 수 없음). 아래와 같이 eval 함수에 대해 설명합니다. 엄격 모드를 사용할 수 있습니다:
Chrome 브라우저에서 엄격 모드의 오류를 올바르게 보고하려면 코드 외부에 즉시 실행 기능을 래핑하거나 기타 유사한 조치를 취해야 합니다.
(function(){ 'use strict' name = "reeoo"; console.log(name) })()
그렇습니다
FireFox 코드 스크래치 페이퍼 디버깅 엄격 모드
Chrome에서는 엄격 모드를 실행하려면 클로저 레이어를 포함해야 합니다. 너무 번거롭기 때문에 엄격 모드 코드를 직접 실행할 수 있는 다른 방법이 있나요?
FireFox에는 직접 실행할 수 있는 코드 스크래치 페이퍼가 있습니다. 바로 가기 키 SHIFT+F4
엄격 모드가 얼마나 엄격한가요
엄격 모드의 몇 가지 중요한 제한 사항
1. 변수 선언
선언되지 않은 변수 사용은 허용되지 않습니다
"use strict"; name = "reeoo";
오류 보고(코드 초안, 아래와 동일)
예외: ReferenceError: 선언되지 않은 변수 이름에 할당
2. 읽기 전용 속성 값 수정
"use strict"; var testObj = Object.defineProperties({}, { prop1: { value: 10, writable: false // 一个只读的属性 }, prop2: { get: function () { } } }); testObj.prop1 = 20; //尝试改变prop1的值 testObj.prop2 = 30;//尝试改变prop2的值
엄격 모드에서는 오류가 보고됩니다.
잡히지 않은 TypeError: #a87fdacec66f0909fc0757c19f2d2b1d
의 읽기 전용 속성 'prop1'에 할당할 수 없습니다.
가장 엄격하지 않은 모드는 값을 할당할 수 없으며 오류가 보고되지 않음을 의미합니다
3. 확장 불가능한 속성 수정
은 확장 가능 속성이 false로 설정된 개체에 속성을 추가하는 것처럼 동작합니다.
"use strict"; var testObj = new Object(); Object.preventExtensions(testObj);//经过这个方法处理过的对象,不影响原有对象的删除,修改.但是无法添加新的属性成员了. testObj.name = "reeoo";
엄격 모드 오류:
잡히지 않은 유형 오류: 속성 이름을 추가할 수 없습니다. 개체는 확장할 수 없습니다
비엄격 모드는 오류를 보고하지 않지만 testObj는 확장되지 않습니다.
4. 변수, 함수, 매개변수 삭제
구성 가능한 속성이 false로 설정된 속성을 제거합니다.
"use strict"; var testvar = 15,testObj={}; function testFunc() {}; delete testvar; delete testFunc; Object.defineProperty(testObj, "testvar", { value: 10, configurable: false }); delete testObj.testvar;
报错:
Uncaught SyntaxError: Delete of an unqualified identifier in strict mode.
5、在一个对象文本中多次定义某个属性
严格模式下不允许一个属性有多个定义
"use strict"; var testObj = { prop1: 10, prop2: 15, prop1: 20 };
报错(node控制台)
Duplicate data property in object literal not allowed in strict mode
正常模式中后声明的重复的变量会覆盖前面声明的,而且不会报错。
注:这个问题在ECMAScript6中已被修复。
6、严格模式下不允许形参参数名称重复
"use strict"; function testFunc(param1, param1) { return 1; };
报错:
Uncaught SyntaxError: Duplicate parameter name not allowed in this context
7、无法使用标识符的未来保留字。严格模式下将保留标识符名称
一下标识符(ES6中依然没有实现的)在严格模式中是不能使用的,否则也会报错。
用了就是这个下场:
Uncaught SyntaxError: Unexpected strict mode reserved word
8、严格模式下不允许使用八进制数字参数和转义字符
"use strict"; var testoctal = 010; var testescape = \010;
报错:
Uncaught SyntaxError: Unexpected token ILLEGAL(…)
9、当this 的值为 null 或 undefined 时,该值不会转换为全局对象
比如:
"use strict"; function testFunc() { return this; } var testvar = testFunc();
在非严格模式下,testvar 的值为全局对象window,但在严格模式下,该值为 undefined。
10、字符串"eval"不能用作标识符(变量或函数名、参数名等)
"use strict"; var eval = "hehe";
Uncaught SyntaxError: Unexpected eval or arguments in strict mode
11、在严格模式下,函数声明无法嵌套在语句或块中。它们只能显示在顶级或直接显示在函数体中
"use strict"; var arr = [1, 2, 3, 4, 5]; var index = null; for (index in arr) { function myFunc() {}; }
node控制台:
SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.
但是这个限制已经在ES6中被修复
12、严格模式下eval用法无效
如果在 eval 函数内声明变量,则不能在此函数外部使用该变量。
"use strict"; eval("var testvar = 10"); console.log(testvars);
Uncaught ReferenceError: testvar is not defined
13、严格模式下"arguments"用法无效
字符串”arguments”不能用作标识符(变量或函数名、参数名等)。
"use strict"; var arguments = 1;
Uncaught SyntaxError: Unexpected eval or arguments in strict mode
这个跟上面第10条的限制是差不多的。
14、函数内的 arguments,无法更改arguments 对象的成员的值
"use strict"; function testArgs(oneArg) { arguments[0] = 20; }
在非严格模式下,可以通过更改 arguments[0] 的值来更改 oneArg 参数的值,从而使 oneArg 和 arguments[0] 的值都为 20。在严格模式下,更改 arguments[0] 的值不会影响 oneArg 的值,因为 arguments 对象只是一个本地副本。
15、不允许使用arguments.callee
"use strict"; function my(testInt) { if (testInt-- == 0) return; arguments.callee(testInt--); } my(100);
用了的下场就是这样:
Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
16、不允许使用with
"use strict"; with (Math){ x = cos(3); y = tan(7); }
Uncaught SyntaxError: Strict mode code may not include a with statement
为什么要使用严格模式
既然这种模式这么多限制,我为什么还要用呢?闲得蛋疼吗?当然8是,
JavaScript作为一门一开始用于浏览器的脚本语言,容错性非常好,即使有时候你的代码写的不标准,也不会报错,但这有时候会变成代码隐患。开启了严格模式之后,JavaScript的一些不合理的不严谨的语法都会得到控制,让你能够更严谨的书写JavaScript代码,成为一个更好的程序员。严格模式是ES5时代的产物,ES2015已经在普及的路上,是时候使用严格模式了!