본문 바로가기
Spring/JavaScript+Jsp(HTMl)

[ JS ] strict mode(use strict) 엄격모드

by snow_hong 2022. 3. 16.

 

Strict 모드의 장점

1. JavaScript 오류는 아니지만 함정이 될 어떤 일을 오류가 발생하도록 변경하여 제거한다                                    (코드의 문제를 더 빨리 알리고 소스로 더 빨리 안내하므로, 결과적으로 디버깅이 쉬워진다.)

2. JavaScript 엔진의 최적화 처리를 어렵게 만드는 오류를 수정한다. (동일한 코드보다 빠르게 수행 할 수 있다.)

3.미래의 ECMAScript로 정의 될 예정 구문을 금지한다. (발생가능한 에러를 예방)


[ Strict 모드 사용법 ]

엄격모드를 전체 스크립트에 적용하기 위해, 정확한 구문 "use strict";(또는 'use strict';) 을 다른 구문 작성 전에 삽입

1. 스크립트에서 Strict mode 적용

// 전체 스크립트 엄격 모드 구문
"use strict"; 
var v = "Hi! I'm a strict mode script!";

 

2. 함수에 Strict mode 적용

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."; }

 

3. 모듈에 Strict mode 적용

function strict() {
    // 모듈이기때문에 기본적으로 엄격합니다
}
export default strict;

[ 실수를 에러로 변환(Converting mistakes into errors) ]

자바스크립트는 오류를 어느정도 무시하고 넘어갈 수 있습니다. 이것이 편하게 코딩을 할 수 있게 하지만, 때로는 심각한 버그를 만들게 됩니다. strict 모드는 이러한 실수를 에러로 변환하여 즉시 수정할 수 있게 합니다.

아래의 코드들은 strict 모드가 아닌 경우, 에러가 발생하지 않지만, 해당 코드는 무시됩니다.

- 선언하지 않고 전역 변수를 만들 수 없다.

"use strict";
                       // 전역 변수 test 이 존재한다고 가정
tasd = 17; // 변수의 오타 때문에(즉, 변수 선언하지 않고 변수사용)
               //이 라인에서 ReferenceError 를 발생시킴

 

- writable이 false로, 읽기 전용 객체에 쓰는 것이 불가능 합니다. (read only 객체 수정 불가능)

"use strict"; 
var testObj = Object.defineProperties({}, {
 prop1: { value: 10,
 writable: false // by default 
}, 
prop2: { 
get: function () {
 } 
} 
});

testObj.prop1 = 20;  // TypeError 발생
testObj.prop2 = 30; // TypeError 발생

 

- get으로 선언된 객체는 수정할 수 없습니다. (getter-only property 수정 불가능)

// getter-only 프로퍼티에 할당
"use strict"; 
var obj2 = { get x() { return 17; } };
obj2.x = 5; // TypeError 발생

 

- extensible 특성이 false로 설정된 객체에 속성을 확장 할 수 없습니다. (확장 불가 객체 확장 불가능)

// 확장 불가 객체에 새 프로퍼티 할당
"use strict"; 
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // TypeError 발생

 

- delete를 호출 할 수 없습니다

"use strict";
delete Object.prototype; // TypeError 발생

 

- 리터럴 객체는 동일한 이름의 property를 가질 수 없습니다.(하지만ES6는 가능함)

"use strict"; 
var o = { p: 1, p: 2 }; // !!! syntax error

 

- 함수의 동일한 매개 변수 이름을 선언하는 것이 불가능 합니다.

function sum(a, a, c){ // !!! 구문 에러
  "use strict";
  return a + b + c; // 코드가 실행되면 잘못된 것임
}

 

- 8진수 숫자 리터럴 및 이스케이프 문자를 사용 할 수 없습니다.

"use strict";
var a = 0o10; // ES6: 8진수
-------
var sum = 015 + // !!! 구문 에러
          197 +
          142;

 

- primitive values의 속성 설정이 불가능합니다.

(function() {
"use strict";

false.true = "";         // TypeError
(14).sailing = "home";   // TypeError
"with".you = "far away"; // TypeError

})();

[ 변수 사용의 명료화 (Simplify variable uses) ]

strict 모드는 변수 이름의 맵핑을 단순화 합니다. 대부분의 컴파일러의 최적화는 변수의 매핑에 달려 있습니다. 자바스크립트 또한 변수의 매핑이 최적화의 크리티컬 이슈입니다. strict 모드를 사용하여 자바스크립트를 최적화 할 수 있습니다.

- with를 사용할 수 없습니다.

"use strict";
var x = 17;
with (obj) // !!! 구문 에러
{
  // 엄격모드가 아니라면, 이는 var x 가 되어야 하나요,
  // obj.x 가 되어야 하나요?
  // 일반적으로는 코드를 실행하지 않고 이를 말하는 것은 불가하므로,
  // 이름을 최적화 할 수 없습니다.
  x;
}

 

- eval 함수는 주변 스코프에 새로운 변수를 추가하지 않습니다.

var x = 17;
var evalX = eval("'use strict'; var x = 42; x");
console.assert(x === 17);
console.assert(evalX === 42);

[ eval과 arguments 명료화 ] (Making eval and arguments simpler)

strict 모드는 eval과 arguments 사용을 더욱 명료하게 사용 할 수 있게 합니다.

- eval을 변수 또는 함수, 매개 변수의 이름으로 사용할 수 없습니다.

"use strict";
 eval = 17; 
++eval; 
var eval;
 function x(eval) { } 
var y = function eval() { };
 //SyntaxError

 

- arguments를 변수 또는 함수, 매개 변수의 이름으로 사용할 수 없습니다.

"use strict"; 
arguments++; 
var obj = { set p(arguments) { } };
 try { } catch (arguments) { } 
function arguments() { }
var f = new Function("arguments", "'use strict'; return 17;");
 //SyntaxError

 

- 인자값을 수정함으로 arguments의 값이 수정되지 않습니다.

function f(a){ 
"use strict"; 
a = 42;
 return [a, arguments[0]]; 
} 
var pair = f(17);
 console.log(pair[0]); 
console.log(pair[1]);

 

- callee를 지원하지 않습니다.

"use strict"; 
var f = function() { return arguments.callee; }; 
f(); // throws a TypeErrorr

[ 안전한 자바스크립트 ("Securing" JavaScript) ]

strict 모드를 사용하면 보안에 강한 자바스크립트를 작성할 수 있습니다. 일부 웹 사이트에서 사용자에게 자바스크립트를 작성할 수 있는 기능을 제공합니다. 이 때 사용자가 작성한 자바스크립트는 부분적으로 접근을 금지해야 합니다. 접근을 막기 위하여 런타임에 체크를 한다면 비효율적인 코드가 됩니다. 이러한 문제를 strict 모드를 사용하여 해결 할 수 있습니다.

- this의 값이 null 또는 undefined인 경우 전역 객체로 변환하지 않습니다.

this의 결과가 undefined의 경우 window 객체로 변환하지 않고, undefined가 그대로 보이게 됩니다.

"use strict";
function fun() { return this; }
console.log(fun());
console.log(fun.call(2));
console.log(fun.apply(null));
console.log(fun.call(undefined));
console.log(fun.bind(true)());

 

- callee, caller를 통해 stack 검색이 불가능합니다.

function restricted() { 
"use strict"; 
restricted.caller; // throws a TypeError 
restricted.arguments; // throws a TypeError 
} 
function privilegedInvoker() {
 return restricted(); 
} 
privilegedInvoker();

 

- arguments의 caller를 지원하지 않습니다.

"use strict";
 function fun(a, b) { 
"use strict"; 
var v = 12;
 return arguments.caller; // throws a TypeError 
} 
fun(1, 2); // doesn't expose v (or a or b)

현재 ECMA Script는 arguments.caller를 제공하지 않습니다. 하지만 이전의 버전에서는 arguments.caller를 제공되어 왔습니다. strict 모드 사용시 이전의 ECMA Script에서도 arguments.caller 사용이 불가능합니다.


[ 미래의 자바스트립트 준비 ] (Paving the way for future ECMAScript versions)

strict 모드는 미래의 자바스크립트 버전 도입을 위하여 몇가지 제한 사항을 적용합니다. strict 모드로 몇가지를 제한 하기 때문에, 추후의 자바스크립트 버전에 적용하기 쉽습니다. 즉 향후 업데이트 될 자바스크립트 버전 대응이 용이합니다.

- 예약된 키워드의 이름으로 변수 또한 함수를 생성할 수 없습니다.

"use strict" 
var implements = ""; 
var interface = ""; 
var package = ""; 
var private = ""; 
var protected = ""; 
var public = ""; 
var static = ""; 
var yield = "";

 

- 함수 선언은 스크립트나 함수의 최상위에서 해야 합니다.

"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
}

strict 모드에서 함수는 최상위에서 선언해야 합니다. 이후의 자바스크립트 버전은 최상위에서 선언하지 않은 함수는 다른 의미를 줄 수 있기 때문에, strict 모드에서 최상위에서 함수를 선언하게 함으로 추후에 나올 자바스크립트 버전을 쉽게 대응할 수 있게 합니다.


[ 참고 사이트 ]

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Strict_mode

https://beomy.tistory.com/13

728x90

댓글