Web/모던 자바스크립트 Deep Dive

[모던 자바스크립트 Deep Dive] 20. strict mode

동띵 2023. 9. 12. 09:28

strict mode란?


  • 만약 함수 내에서 선언하지 않은 변수에 값을 할당할 경우, 변수를 찾아야 할당할 수 있기때문에 자바스크립트 엔진은 스코프 체인을 통해 변수를 검색함 → 해당 함수의 스코프에서 변수 찾기를 실패하면 그 함수 컨텍스트의 상위 스코프에서 변수를 검색함 → 전역 스코프에서도 변수가 없다면 ReferenceError를 발생시키는 것이 아닌 암묵적으로 전역 객체에 변수를 동적 생성함 ⇒ 암묵적 전역
  • 개발자의 의도와 상관없이 발생한 암묵적 전역은 오류 발생 가능성을 높임 ⇒ var, let, const 키워드를 사용하여 변수를 선언 후 사용해야 함
  • strict mode : 자바스크립트 언어의 문법을 좀 더 엄격히 적용하여 오류를 발생시킬 가능성이 높거나, 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러 발생
    • 잠재적인 오류를 발생시키기 어려운 개발 환경을 만들어줌
  • ESLint 같은 린트 도구를 통해 strict mode와 유사한 효과 얻기 가능
    • 린트 도구는 정적 분석 기능을 통해 소스코드 실행 전에 소스코드의 문법적 오류잠재적 오류까지 찾아내고 오류의 원인을 리포팅해줌
    • 코딩 컨벤션을 설정 파일 형태로 정의하고 강제할 수 있음

strict mode의 적용


  • 전역의 선두 또는 함수 몸체의 선두에 ‘use strict’; 추가
    • 전역의 선두에 추가하면 스크립트 전체에 strict mode 적용
    • 'use strict'; function foo() { x = 10; // ReferenceError: x is not defined } foo();
    • 함수 몸체의 선두에 추가하면 해당 함수중첩 함수에 strict mode 적용
    • function foo() { 'use strict'; x = 10; // ReferenceError: x is not defined }
  • 코드의 선두에 ‘use strict’;를 위치시키지 않으면 strict mode 제대로 동작하지 X
  • function foo() { x = 10; // 에러 발생 X 'use strict'; }

전역에 strict mode를 적용하는 것은 피하자


  • 전역에 적용한 script mode는 스크립트 단위로 적용됨 → strict mode와 non-strict mode 스크립트를 혼용하는 것은 오류를 발생시킬 수 있음 → 즉시 실행 함수로 스크립트 전체를 감싸서 스코프를 구분하고 즉시 실행 함수의 선두에 strict mode 적용
(function() {
	'use strict';

	// Do something
}())

함수 단위로 strict mode를 적용하는 것도 피하자


  • 함수 또한 strinct mode와 non-script mode를 혼용하여 적용하는 것은 바람직하지 않고, 함수 일일이 strict mode를 적용하는 것은 번거로움
  • strict mode가 적용된 함수가 참조할 함수 외부의 컨텍스트에 strict mode를 적용하지 않으면 문제 발생

⇒ strict mode는 즉시 실행 함수로 감싼 스크립트 단위로 적용하는 것이 바람직

strict mode가 발생시키는 에러


암묵적 전역

  • 선언하지 않은 변수 참조 시 ReferenceError

변수, 함수, 매개변수의 삭제

  • delete 연산자로 변수, 함수, 매개변수 삭제 시 SyntaxError

매개변수 이름의 중복

  • 중복된 매개변수 이름 사용 시 SyntaxError

with 문의 사용

  • with 문 사용 시 SyntaxError
    • with 문 : 전달된 객체를 스코프 체인에 추가 (동일한 객체의 프로퍼티를 반복해서 사용할 때 객체 이름을 생략할 수 있어서 코드가 간단해지지만, 성능과 가독성이 나빠짐)

strict mode 적용에 의한 변화


일반 함수의 this

  • 함수를 일반 함수로서 호출하면 this에 undefined가 바인딩
    • 생성자 함수가 아닌 일반 함수 내부에서 this를 사용할 필요가 없기 때문
(function() {
	'use strict';
	
	function foo() {
		consle.log(this); // undefined
	}
	foo(); // 일반 함수로서 호출

	function Foo() {
		consle.log(this); // Foo
	}
	new Foo(); // 생성자 함수로서 호출

}())

arguments 객체

  • 매개변수에 전달된 인수를 재할당하여 변경해도 arguments 객체에 반영 X
(function(a) { 
    'use strict'; 
    a = 2; 
    console.log(arguments); // {0: 1, length: 1}
}(1))