[Effective JavaScript] 변수 호이스팅

김범식·2023년 6월 20일
0

Effective JavaScript

목록 보기
14/33
post-thumbnail

자바스크립트는 블록 단위의 스코프를 지원하지 않는다. 변수 정의는 이를 포함한 가장 가까운 선언문이나 블록으로 스코프가 정해지는것이 아니라, 자신을 포함하는 함수에 의해 지정된다.

function isWinner(player, others){
	var highest = 0;
	for( var i = 0 , n =others.length;i<n;i++){
		var player = other[i];
		if(player.score > highest){
			highest = player.score;
		}
	}
	return player.score > highest;
}





자바스크립트의 변수는 블록에 의해서가 아니라 함수에 의해서 스코프가 정해지기 때문에 player의 내부 선언은 이미 스코프 안에 선언된 변수 즉 player 파라미터재선언 하는것일 뿐이다.

그결과 player를 함수의 원래 player인자가 아닌 마지막 요소로 보게 된다.

자바 스크립변수 선언의 동작을 선언할당 부분으로 나누어서 이해하면 좋다. 선언부분은 끌어올리고, 할당 부부은 그자리에 그대로 둔다.

function f(){
	//..
	//..
	{
		var x = /*...*/;
		//...
	}
	/...
}

호이스팅 결과

function f(){
	var x
	//..
	//..
	{
		x = /*...*/;
		//...
	}
	/...
}

이러한 호이스팅은 재선언할 때 혼란을 초래할 수 있다. 동일한 함수 내에서 같ㅌ은 변수를 여러번 정의하는 것은 허용되지 않는다.

function trimSections(header, body, footer){
	for(var i = 0, n = header.length;i++){
		header[i] = header[i].trim();
	}
	for(var i = 0, n = body.length;i++){
		body[i] = body[i].trim();
	}
	for(var i = 0, n = footer.length;i++){
		footer[i] = footer[i].trim();
	}
}

호이스팅이 된 이후에는 선언부가 위로 올라가게 된다.

function trimSections(header, body, footer){
	var i,n;
	for( i = 0, n = header.length;i++){
		header[i] = header[i].trim();
	}
	for( i = 0, n = body.length;i++){
		body[i] = body[i].trim();
	}
	for( i = 0, n = footer.length;i++){
		footer[i] = footer[i].trim();
	}
}

i, n은 각각 한번만 선언되고 재할당 된것이다.

재선언은 별도의 변수를 나타내기 때문에, 어떤 프로그래머들은 효과적으로 모호함을 줄이기 위해 변수들을 직접 호이스팅하여 함수 맨 윗부분에 올리기도 한다.

자바스크립트가 블록 스코프가 지원되는 예외 상황중 하나는 바로 exception이다.

try…catchexception을 잡아 변수로 바인딩하고, 해당 변수는 catch블록 안에서만 스코프가 적용된다.

function test(){
	var x = "var", result = [];
	result.push(x);
	try{
			throw "exception";
	}catch(x){
			x = "catch";  //catch 안에서만 적용됨 
	}
	result.push(x);
	return result;
}

test(); //["var,"var"]
	




let, const


JavaScript에서 letconst는 변수를 선언하는 데 사용되는 키워드ek, 이들은 var 키워드와는 몇 가지 중요한 차이점을 가지고 있다.

  1. 블록 스코프: letconst는 블록 스코프를 가집니다. 즉, 변수를 선언한 블록 내에서만 유효하며 블록 외부에서는 접근할 수 없다. 반면에 var함수 스코프를 가지므로 변수가 함수 내에서 선언된 경우에도 함수 내 어디서든 접근할 수 있다.. 블록 스코프는 코드의 가독성을 높이고 변수의 충돌 가능성을 줄여준다.
  2. 호이스팅: letconst는 호이스팅이 발생하지 않는다. 호이스팅은 변수를 선언하기 전에도 변수를 참조할 수 있는 JavaScript의 동작이다. var로 선언한 변수는 선언부가 스코프의 맨 위로 끌어올려지기 때문에 호이스팅이 발생한다. 반면에 letconst는 호이스팅되지 않으므로 변수를 선언하기 전에 참조하면 ReferenceError가 발생합니다. 이는 변수를 선언하기 전에 사용하는 실수를 방지할 수 있다.
  3. 재할당과 불변성: let은 재할당이 가능한 변수를 선언할 때 사용되고, const는 재할당이 불가능한 상수를 선언할 때 사용된다. const로 선언한 변수는 초기화한 후에 다른 값을 할당할 수 없다. 이를 통해 코드의 의도를 명확히 하고, 불변성을 유지할 수 있다. 반면에 let은 재할당이 가능하므로 변수의 값을 변경할 수 있다.

따라서, letconst를 사용하는 것은 코드의 가독성을 향상시키고 버그를 방지하는 데 도움이 되며, 변수의 스코프와 불변성을 명확하게 관리할 수 있게 해줍니다. var는 예전에 사용되던 구식의 변수 선언 방식이므로, 가능하면 letconst를 사용하는 것이 권장됩니다.



기억할 점

  • 블록 내에서의 변수 선언은 암묵적으로 그 변수를 포함하는 함수의 맨 윗부분으로 호이스팅 된다.
  • 변수의 재선언은 하나의 변수처럼 처리된다.
  • 혼란을 막기위해 지역변수 선언을 직접 호이스팅하는 것을 고려해라
profile
frontend developer

0개의 댓글