TIL 15 day 'use strict';

Winney·2020년 9월 13일
1
post-thumbnail

'use strict';

처음 자바스크립트를 배울 때 앞으로 자바스크립트 공부를 하면서 반드시 'use stirct';를 제일 상단에 쓰는 것부터 하라고 배웠었다. 당시 들었던 이유는 자바스크립트가 가지고 있는 유연성 때문에 다른 프로그래밍언어에서는 허용되지 않는 것들이 자바스크립트에서는 허용이 되고 그로 인한 문제를 막기 위해 다른 프로그래밍 언어와 비슷하게 자바스크립트 코드를 작성하기 위해 사용한다고 정도만 알고 있었다.
하지만 최근에 내가 사용하는 것들에 대해 다시 명확히 해야할 필요성을 느껴서 'use strict';에 관한 MDN의 글을 읽어보았다.

엄격모드란?

엄격모드는 'use strict';를 말한다. 이는 ECMAScript5에서 추가되었다. 엄격모드는 JavaScrip에서 암묵적으로 지원하던 느슨한모드(sloppy mode)를 해제하기 위한 모드이다. 엄격모드는 일반코드와 다른 의미(semantic)를 가지고 있다. 엄격모드를 지원하지 않는 브라우저에서 피쳐 테스트(feature-testing) 없이 엄격모드에 의존할 경우 코드는 다른 방식으로 동작할 것이다.
대부분의 브라우저는 엄격모드를 지원하고 있지만 대표적으로 IE9이하버전에서는 엄격모드를 적용하지 않기 때문에 사용에 주의해야한다.

엄격모드 사용 시 JavaScript에 생기는 의미(semantics) 변경들
1. 기존에 무시되던 에러를 throwing한다.
2. JavaScript 엔진의 최적화를 어렵게 하는 실수를 바로잡는다. 그로인해 가끔 엄격모드는 비엄격모드에 비해 더 빨리 작동한다.
3. 엄격모드는 ECMAScript 차기 버전에서 사용 될 문법을 금지한다.

1. 엄격모드 적용

1. 전체 스크립트에 적용

스크립트 상단에 'use strict';를 삽입한다.
단, 엄격모드와 비엄격모드의 스크립트를 연결 할 경우 전체 스크립트는 엄격모드로 보이게 된다. 그로인해 비엄격모드의 스크립트가 정상작동 하지 않을 수 있기 때문에 둘을 연결하는 것은 매우 조심해야한다.
엄격모드와 엄격모드, 비엄격모드와 비엄격모드의 연결은 괜찮다.

2. 함수에 적용

함수에만 'use strict';를 적용 할 수 있다. 함수 본문의 처음에 'use strict';를 삽입하면 된다.

function strict() {
'use strict'; //함수 내 엄격모드 적용
	//함수 내용
};

3. 모듈에 적용

ECMAScript2015에서 JavaScript모듈이 소개되었다. JavaScript의 전체 컨텐츠는 엄격모드 구문('use strict';)이 없어도 자동으로 엄격모드이다.

function strict() {
    // 모듈이기때문에 자동으로 엄격모드이다.
}
export default strict;

2. 엄격모드 변경

1. 실수를 에러로 바꾼다.

엄격모드는 이전에 허용되던 실수를 에러로 바꿔놓는다.

1. 엄격모드는 실수로 글로벌 변수를 생성하지 못하게 한다.

일반적으로 JavaScript에서 변수선언 없이 값을 할당해도 변수선언을 한 것으로 간주하고 에러가 나지 않는다. 하지만 엄격모드에서는 이를 ReferenceError로 간주한다.

'use strict';

mistypedVariable = 10; // ReferenceError

2. 엄격모드는 예외를 발생시켜 실수를 조용히 넘어가는 대신 에러가 발생하게 한다.

예를 들어 NaN은 전역변수로 쓸 수 없다. 때문에 NaN에 할당되는 일반적인 코드는 아무것도 할 수 없고 개발자도 실패 메세지를 받지 않는다. 하지만 엄격모드는 이에 에러를 날린다.

"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. 엄격모드는 삭제 할 수 없는 프로퍼티를 삭제하려고 할 때 에러를 발생시킨다.

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

4. 엄격모드는 유니크한 매개변수(parameter)를 요구한다.

비엄격모드에서는 마지막으로 중복된 인수가 이전에 지정된 인수를 숨긴다. 이런 것들은 arguments[i]를 통해 접근 할 수 있다. 하지만 이것은 적절하지 않기 때문에 엄격모드에서는 이를 에러처리한다.

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

5. ECMAScript5에서 엄격모드는 8진구문을 금지한다.

8진구문이 ES5의 문법은 아니나 모든 브라우저 앞에 0을 붙여지원한다. ECMAScript2015에서는 접두사 '0o'를 붙여 8진수를 지원한다.

var a = 0o10; // ES6: 8진수

초보 개발자의 경우 0이 무의미하다고 생각해 정렬에 0을 앞에 붙여사용한다. 하지만 이는 숫자의 의미를 바꿀 수 있으므로 엄격모드에서 이는 에러이다.

"use strict";
var sum = 015 + // !!! 구문 에러
          197 +
          142;

6. ECMAScript6의 엄격모드는 primitive 값에 프로퍼티를 설정하는 것을 금지한다.

비엄격모드일 때는 프로퍼티설정이 무시되지만 엄격모드에서는 TypeError를 발생시킨다.

(function() {
"use strict";

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

})();

이 외에도 엄격모드 변경은 변수사용을 단순화하며 eval 과 arguments 를 더 간단하게 하고 보안된 JavaScript 작성을 쉽게 해준다. 하지만 아직 여기에 대해서 읽어도 잘 모르겠고 좀 더 익히고 이해하게 되면 다시 추가해서 정리를 할 생각이다.

profile
프론트엔드 엔지니어

2개의 댓글

comment-user-thumbnail
2020년 9월 13일

오 좋은 글 감사합니다. 막연하게 use strict를 적고나서도.... 코딩할 때는 그냥 유연성을 좀더 엄격하게 해준다 정도만 생각하고있었는데
이렇게 정리해주신 글을 읽어보니 저도 머리속에서 내용이 차곡차곡 정리되네요. TIL 꾸준히 쓰시는 것 같은데 앞으로도 좋은 글 기대하겠습니다!

1개의 답글