[Node.js] use strict란? 왜 쓰는거야?

KIM SOO MIN·2023년 11월 27일

learning

목록 보기
4/16

Strict mode

💡 Strict mode (엄격 모드) ←→ default Sloppy mode (느슨한 모드)
기존에는 조용히 무시되던 에러들을 throwing
JavaScript 엔진의 최적화 작업을 어렵게 만드는 실수를 바로잡음
느슨한 모드의 동일한 코드보다 더 빨리 작용되기도 함
Strict mode 적용하기

전체 스크립트에 적용
// 전체 스크립트 엄격 모드 구문

'use strict';
var v = "Hi!  I'm a strict mode script!";

Strict mode와 Sloppy mode의 스크립트 연결은 문제를 일으킬 수 있기 때문에 심사숙고해야 한다.
사용해야 한다면, 함수를 기준으로 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."; }

함수 본문 처음에 넣는다.
모듈에 적용

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

모듈은 자동으로 Strict mode이다.
실수를 에러로 바꾸는 것

실수로 글로벌 변수를 생성하는 것을 불가능하게 함

"use strict";

aaa2 = 1; // 전역 변수 aaa1이 존재한다고 가정

일반적인 JavaScript에서 변수를 잘못 입력하면 전역 객체에 대한 새 속성이 만들어지고 그대로 동작하나, Strict mode에서는 오류를 발생
예외를 발생

"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 발생
일반 코드에서 조용히 넘어가는 모든 실패에 대해 예외를 발생시킴
삭제할 수 없는 프로퍼티를 삭제하려 할 때 예외 발생
"use strict";

delete Object.prototype; // TypeError 발생
유니크한 함수 파라미터 이름 요구
function sum(a, a, c){ // !!! 구문 에러
  "use strict";
  return a + b + c; // 코드가 실행되면 잘못된 것임
}

8진 구문 금지
접두사 0o를 붙여 8진수 지원
0 을 붙인 8진수는 Strict mode에서 에러
primitive 값에 프로퍼티 설정 금지

"use strict";

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

변수 사용 단순화

with 사용 금지
런타임 중에 블록 안의 모든 이름이 전달된 객체의 프로퍼티나 인근 또는 전역 스코프 내의 변수로 매핑될 수도 있음
엄격모드의 eval은 새로운 변수를 주위 스코프에 추가하지 않음

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'; '엄격모드 코드!'");

일반 이름을 제거하는 것을 금지


var x;
delete x; // !!! 구문 에러

eval("var y; delete y;"); // !!! syntax error

eval과 arguments를 더 간단하게

변수명 eval과 arguments는 언어 문법에 바운드되거나 할당 될 수 없음

"use strict";

// ALL error
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 객체가 생성한 프로퍼티에 별칭을 지정하지 않음
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);

arguments.callee는 더 이상 지원되지 않음
JavaScript 보안

자바스크립트는 사용자의 개인정보에 접근할 수 있고, 자바스크립트의 유연성으로 인해 많은 런타임 체크가 필요함
Strict mode를 사용하면 특정 방식으로 호출되므로 런타임 검사의 필요성이 크게 줄어들게 됨
this로 함수에 전달된 값은 강제로 객체가 되지 않음


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);

정의 되지 않은 this는 undefined가 됨
window 객체를 this를 통해 참조할 수 없음
확장을 통해 자바스크립트 스택을 걷는 것이 불가능

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

인수는 해당 함수의 호출 변수에 대한 접근을 제공하지 않음

"use strict";

function fun(a, b)
{
  "use strict";
  var v = 12;
  return arguments.caller; //TypeError 가 발생.
}
fun(1, 2); // doesn't expose v (or a or b)
profile
3년차 풀스택 엔지니어입니다.

0개의 댓글