JS/[책] 모던 JS deep dive

20강 - strict mode

web_seul 2022. 3. 5. 12:22

20.1 strict mode란?

function foo(){
	x = 10;
}
foo();

console.log(x);

 

JS엔진은 변수 x가 선언된 위치를 찾기위해 스코프 체인을 통해 검색(foo함수 스코프 -> 전역 스코프)

변수의 선언이 존재하지않으므로 ReferenceError를 예상하나 JS엔진은 암묵적으로 전역 객체에 x 프로퍼티를 동적 생성하여 전역변수처럼 사용하도록 함(암묵적 전역, implicit global)

-> 오류 발생의 원인이 될수있므로 var, let, const를 필수적으로 사용!

 

실수 방지를 위해 ES5부터 strict mode(엄격모드) 추가 : 오류발생 가능성이 있거나 JS엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러 발생

ESLint는 정적 분석기능을 통해 소스코드 실행전 코드를 스캔하여 문법적 오류, 잠재적 오류를 찾아내고 오류의 원인을 리포팅해주는 도구로 코딩 컨벤션을 설정 파일 형태로 정의하고 강제할 수 있으므로 strict mode보다 선호

https://poiemaweb.com/eslint 

 

ESLint | PoiemaWeb

코드 linting은 특정 스타일 가이드를 따르지 않거나 문제가 있는 패턴이나 코드를 찾기 위해 사용되는 정적 분석 툴이다. ESLint는 처음부터 유용하게 사용할 수있는 built-in rule을 제공하지만 개발

poiemaweb.com

 

20.2 strict mode의 적용

전역의 선두 또는 함수 몸체의 선두에 'use strict' 선언

'use strict';
function foo(){
	x = 10; //ReferenceError
}
foo();

 

function foo(){
'use strict';
	x = 10; //ReferenceError
}
foo();

 

function foo(){
	x = 10;
    'use strict';
}
foo();

console.log(x);

 

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

전역에 적용한 strict mode는 스크립트 단위로 적용되므로 다른 스크립트에 영향을 주지않아 이 부분이 오류를 발생시킬 수 있다. (ex. non-strict mode의 외부라이브러리를 사용할 경우)

<!DOCTYPE html>
<html>
<body>
    <script>
    'use strict';
    </script>
    
    <script>
    x = 1; //에러발생x
    consolg.log(x); //1
    </script>
    
    <script>
    'use strict';
    y = 1; //ReferenceError: y is not defiend
    console.log(y);
    </script>
</body>
</html>

 

이런 경우 즉시 실행 함수로 스크립트 전체를 감싸서 스코프를 구분하고 즉시 실행 함수의 선두에 strict mode를 적용하도록 한다.

(function (){
	'use strict';
	//Do something//
}());

 

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

모든 함수에 일일이 strict mode를 적용하는 것은 비효율적이며 strict mode의 함수가  참조할 함수 외부의 컨텍스트에 strict mode를 적용하지 않은 경우 오류가 발생할 수 있다.

(function(){
    //non-strict mode
    var let = 10; //에러발생x
    
    function foo(){
    	'use strict';
        let = 20; //SyntaxError: Unexpected strict mode reserved word
    }
    foo();
}());

 

20.5 strict mode가 발생시키는 에러

- 암묵적 전역 : 선언하지 않은 변수를 참조할 때 Reference Error 발생

(function(){
    'use strict';
    x = 1;
    console.log(x);
}());

 

- 변수, 함수, 매개변수의 삭제 : delete 연산자로 변수, 함수, 매개변수를 삭제할 경우 SyntaxError 발생 ( JS엔진의 가비지컬렉터로 사용하지 않는 변수 등은 자동으로 삭제되므로 delete 연산자를 잘 사용하지 않음)

(function(){
    'use strict';
	var x = 1;
    delete x; //SyntaxError
    
    function(foo(a){
    	delete a; //SyntaxError
    }
    delete foo; //SyntaxError
}());

 

- 매개변수 이름의 중복

(function(){
    'use strict';
	
    //SyntaxError    
    function foo(x, x){
    	return x + x;
    }
    console.log(foo(1,2));    
}());

 

- with문의 사용 : with문은 전달된 객체를 스코프 체인에 추가하는 역할로 동일한 객체의 프로퍼티를 반복해서 사용할 때 객체 이름을 생략할 수 있어서 코드가간단해지는 효과가 있지만 성능과 가독성이 좋지않으므로 권장x

(function(){
    'use strict';
    
    //SyntaxError
    with( {x:1} ){
    	console.log(x);
    }
}());

 

20.6 strict mode 적용에 의한 변화

- 일반 함수의 this : strict mode에서 일반 함수로 호출하면 생성자 함수가 아닌 일반 함수 내부에서는 this를 사용할 필요가 없으므로 this에 undefined 가 바인딩된다. 에러발생x

(function(){
    'use strict';
    
    function foo(){
    	console.log(this); //undefined
    }
    foo();
    
    function Foo(){
    	console.log(this); //Foo
    }
    new Foo();
}());

 

- arguments 객체 : 매개변수에 전달된 인수를 재할당하여 변경해도 arguments객체에 반영 x

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

반응형

'JS > [책] 모던 JS deep dive' 카테고리의 다른 글

11장. 원시값과 객체의 비교  (0) 2022.12.14
7장. 연산자  (0) 2022.12.07
6장. 데이터 타입  (0) 2022.12.06
5장. 표현식과 문  (0) 2022.12.02
4장. 변수  (0) 2022.12.02