Strict mode (엄격모드)
- ECMAScript 5에서 소개됨
- JavaScript의 제한된 버전을 선택하여 암묵적인 느슨한 모드(Sloppy mode)를 해제하기 위한 방법
특징
- 엄격모드를 지원하지 않는 브라우저(Internet Explorer 10 버전 이하)에서는 엄격 모드의 코드가 다른 방식으로 동작 (그렇기 때문에 엄격 모드에 의존하면 안됨)
- 엄격모드의 code와 비엄격모드의 code는 공존 가능 => 엄격 모드를 일부만 선택하는 것이 점진적으로 가능하게 됨
- 전체 스크립트 또는 부분 함수에 적용 가능
- {} 괄호로 묶여진 block 문, context에 적용되지 않음
엄격모드 사용 시 JavaScript symantic의 변화
1. 기존에 조용히 무시되던 에러들이 throwing
1) 변환 실수를 오류로 해석 (문법 에러, 런타임에러 등)
(1) 글로벌 변수명 틀림
"use strict";
// 전역 변수 mistypedVariable 이 존재한다고 가정
mistypedVaraible = 17; // 변수의 오타때문에 이 라인에서 ReferenceError 를 발생시킴
(2) 사용할 수 없는 변수에 값 할당
"use strict";
// 쓸 수 없는 프로퍼티에 할당
var undefined = 5; // TypeError 발생
var Infinity = 5; // TypeError 발생
// 쓸 수 없는 프로퍼티에 할당
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // TypeError 발생
// getter-only 프로퍼티에 할당
var obj2 = { get x() { return 17; } };
obj2.x = 5; // TypeError 발생
// 확장 불가 객체에 새 프로퍼티 할당
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // TypeError 발생
(3) 삭제할 수 없는 property 삭제 시
"use strict";
delete Object.prototype; // TypeError 발생
(4) 객체 리터럴의 모든 프로퍼티의 이름이 유니크하지 않을 때
"use strict";
var o = { p: 1, p: 2 }; // !!! 구문 에러
※ ECMAScript 2015부터는 에러가 아님
(5) 유니크한 함수 파라미터를 사용하지 않을 때
function sum(a, a, c){ // !!! 구문 에러
"use strict";
return a + b + c; // 코드가 실행되면 잘못된 것임
}
(6) 8진 구문 사용
var a = 0o10; // ES6: 8진수
- ECMAScript5에서 엄격모드는 8진 구문을 금지
- 8진 구문은 ES5의 문법이 아니지만, 모든 브라우저에서 앞에 0을 붙혀야 지원
- ECMAScript2015에서 접두사 "0o"를 붙혀 8진수를 지원
(7) ECMAScript 6 의 엄격모드는 primitive 값에 프로퍼티를 설정하는 것을 금지
(function() {
"use strict";
false.true = ""; // TypeError
(14).sailing = "home"; // TypeError
"with".you = "far away"; // TypeError
})();
- 비엄격모드에서는 무시됨 (no-op)
2. JavaScript 엔진의 최적화 작업을 어렵게 만드는 실수를 바로 잡음
=> 엄격 모드의 코드는 비엄격모드의 동일한 코드보다 더 빨리 작동할 수 있음
1) 변수 사용 단순화
(1) with 사용 불가
"use strict";
var x = 17;
with (obj) // !!! 구문 에러
{
// 엄격모드가 아니라면, 이는 var x 가 되어야 하나요,
// obj.x 가 되어야 하나요?
// 일반적으로는 코드를 실행하지 않고 이를 말하는 것은 불가하므로,
// 이름을 최적화 할 수 없습니다.
x;
}
- with는 런타임 중에 블록 안의 모든 이름이 전달된 객체의 프로퍼티나 다른 스코프 내의 변수로 매핑될 수 있음
- 엄격 모드는 with 를 구문 에러로 만들어, with 의 이름이 런타임에 알 수 없는 위치를 참조하지 않도록 함
(2) 엄격모드의 eval은 새로운 변수를 주의 scope에 추가하지 않음
function strict1(str){
"use strict";
return eval(str); // str 은 엄격모드 코드로 다뤄짐
}
function strict2(f, str){
"use strict";
return f(str); // eval(...) 이 아님:
// str 은 엄격모드를 적용한 경우에만 엄격함
}
function nonstrict(str){
return eval(str); // str 은 엄격모드를 적용한 경우에만 엄격함
}
strict1("'엄격모드 코드!'");
strict1("'use strict'; '엄격모드 코드!'");
strict2(eval, "'느슨한 코드.'");
strict2(eval, "'use strict'; '엄격모드 코드!'");
nonstrict("'느슨한 코드.'");
nonstrict("'use strict'; '엄격모드 코드!'");
- 엄격모드 eval 코드 내의 이름은 엄격모드 코드 내의 이름이 eval 의 결과로 evaluated 되지 않은 것과 동일하게 동작
(3) delete 구문 금지
"use strict";
var x;
delete x; // !!! 구문 에러
eval("var y; delete y;"); // !!! syntax error
2) eval, arguments 단순화
(1) eval과 arguments는 bounding되거나 할당될 수 없음
"use strict";
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;"); // 모두 에러
(2) arguments 객체가 생성한 property를 alias하지 않음
function f(a){
"use strict";
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
(3) arguments.callee 지원하지 않음
"use strict";
var f = function() { return arguments.callee; };
f(); // TypeError
3) 안전한 자바스크립트를 작성하도록 도움
(1) window 객체를 this 를 통해 참조할 수 없음
"use strict";
function fun() { return this; }
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
(2) ECMAScript의 일반적인 확장 사용 불가
function restricted()
{
"use strict";
restricted.caller; // throws a TypeError
restricted.arguments; // throws a TypeError
}
function privilegedInvoker()
{
return restricted();
}
privilegedInvoker();
3. ECMAScript의 차기 버전들에서 정의될 문법 사용을 금지
1) 미래 ECMAScript의 진화에 대비
(1) 예약어와 동일한 이름, 변수, argument로 사용 불가
- 엄격 모드에서의 식별자 후보들은 예약어 (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'; } // !!!
(2) 스크립트나 함수의 top level이 아닌 곳에서의 함수 내용 정의를 제한
"use strict";
if (true){
function f() { } // !!! syntax error
f();
}
for (var i = 0; i < 5; i++){
function f2() { } // !!! syntax error
f2();
}
function baz(){ // kosher
function eit() { } // also kosher
}
※ Sloppy mode (비엄격모드, 느슨한 모드)
- 공식 용어는 아님
- 기본값
엄격모드 적용 방법
1. 전체 스크립트에 엄격 모드 적용
예제)
'use strict';
...
var v = "Hi! I'm a strict mode script!";
- 전체 스크립트에 적용하기 위해 "use strict"; 추가
- 아주 주의하면서 사용해야함
2. 함수에 엄격모드 적용
예제)
function strict() {
// 함수-레벨 strict mode 문법
'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."; }
- 함수 본문 처음에 "use strict"; 추가
- 전체 스크립트에 엄격 모드를 추가하는 것보다 해당 방법을 권장함
3. 모듈에 엄격모드 적용
function strict() {
// 모듈이기때문에 기본적으로 엄격합니다
}
export default strict;
- 위와 같이 사용하면, JavaScript 모듈의 전체 컨텐츠는 자동으로 엄격모드
출처
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Strict_mode
'Programming > JavaScript & TypeScript' 카테고리의 다른 글
[Angular] Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: '' 해결 방법 (0) | 2020.10.08 |
---|---|
Array.prototype.splice() 사용법 (0) | 2020.10.06 |
JavaScript의 Decorator (0) | 2020.09.28 |
[Node.js] 싱글 스레드(Single-thread)와 이벤트 루프(Event loop) (0) | 2020.09.25 |
npm install 시 npm ERR! code EINTEGRITY 에러 해결 방법 (0) | 2020.09.22 |