[Effective JavaScript] 블록-지역 함수 선언문의 스코프에 주의하자

김범식·2023년 6월 26일
0

Effective JavaScript

목록 보기
11/33
post-thumbnail

자바스크립트는 지역 블록안에 함수를 선언하는 표준이 없다. 다음 함수의 맨 윗부부에 함수 선언문을 넣는 방법은 관례적이고 완벽히 정확하다



function f() {return 'global'}
function test(x){
	function f(){ return"local"}
	var result = [];
	if(x){
		result.push(f());
	}
	result.push(f());
	return result;
}

test(true);    //['local', 'local']
test(false);     //['local', 'local']



하지만 f를 지역 블록 안으로 이동시키면 코드는 완전히 달라진다.

function f() {return 'global'}
function test(x){
	
	var result = [];
	if(x){
		function f(){ return"local"} // 런타임환경에 따라 바인딩 되는게 다르다. 
		result.push(f());
	}
	result.push(f()); //false를입력하면 선언만될뿐 할당되지 않기 때문에 에러가 난다. 
	return result;
}

test(true);    //['local', 'local']
test(false);  //에러남



아마도 [’local’,global’] 을 반환하고 그다음에 [’global’]을 반환할 것이라고 예상했을 것이다. 다르게 보면 ['local', 'local']. ['local', 'local'] 을 예상할 수도 있다.



실제로 몇몇 자바스크립트 실행환경은 이같이 동작하지만 모든 실행환경이 이처럼 동작하는것은 아니다. 런타임시 조건적으로 어떤 포함된 블록이 실행되는지에 따라 내부 f를 바인딩한다. (좋지 않다)



어떤 실행환경에서도 올바르게 동작하는 함수를 작성하기 위한 최선의 방법은 함수 선언문을 지역 블록이나 하위 명령에 절대 두지 않는것이다. 최선의 방법은 var 선언문과 함수 표현식을 사용하는 것이다.

function f() {return 'global'}
function test(x){
	
	var result = [];
	var g = f;
	if(x){
		g = function(){ return"local"} // 런타임환경에 따라 바인딩 되는게 다르다. 
		result.push(g());
	}
	result.push(g());
	return result;
}

이방법은 스코프에 대한 궁금증을 해결해준다. 내부 변수는 무조건 지역변수로 바인딩되고, 할당만 조건적으로 실행된다. 따라서 결과 값은 어떤 환경에서든 동일하다.



기억할 점

  • 실행 환경에 따라 다르게 동작할 수 있는 여지가 있으므로, 함수 선언문은 이를 포함하는 함수나 프로그램의 가장 바깥에 두어라
  • 조건적인 함수 선언문 대신, 조건적인 할당문을 이용해 var 선언문을 사용하라
profile
frontend developer

0개의 댓글