자바스크립트는 블록 단위의 스코프를 지원하지 않는다. 변수 정의는 이를 포함한 가장 가까운 선언문이나 블록으로 스코프가 정해지는것이 아니라, 자신을 포함하는 함수에 의해 지정된다.
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…catch
는 exception
을 잡아 변수로 바인딩하고, 해당 변수는 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"]
JavaScript에서 let
과 const
는 변수를 선언하는 데 사용되는 키워드ek, 이들은 var
키워드와는 몇 가지 중요한 차이점을 가지고 있다.
let
과 const
는 블록 스코프를 가집니다. 즉, 변수를 선언한 블록 내에서만 유효하며 블록 외부에서는 접근할 수 없다. 반면에 var
는 함수 스코프를 가지므로 변수가 함수 내에서 선언된 경우에도 함수 내 어디서든 접근할 수 있다.. 블록 스코프는 코드의 가독성을 높이고 변수의 충돌 가능성을 줄여준다.let
과 const
는 호이스팅이 발생하지 않는다. 호이스팅은 변수를 선언하기 전에도 변수를 참조할 수 있는 JavaScript의 동작이다. var
로 선언한 변수는 선언부가 스코프의 맨 위로 끌어올려지기 때문에 호이스팅이 발생한다. 반면에 let
과 const
는 호이스팅되지 않으므로 변수를 선언하기 전에 참조하면 ReferenceErro
r가 발생합니다. 이는 변수를 선언하기 전에 사용하는 실수를 방지할 수 있다.let
은 재할당이 가능한 변수를 선언할 때 사용되고, const
는 재할당이 불가능한 상수를 선언할 때 사용된다. const
로 선언한 변수는 초기화한 후에 다른 값을 할당할 수 없다. 이를 통해 코드의 의도를 명확히 하고, 불변성을 유지할 수 있다. 반면에 let
은 재할당이 가능하므로 변수의 값을 변경할 수 있다.따라서, let
과 const
를 사용하는 것은 코드의 가독성을 향상시키고 버그를 방지하는 데 도움이 되며, 변수의 스코프와 불변성을 명확하게 관리할 수 있게 해줍니다. var
는 예전에 사용되던 구식의 변수 선언 방식이므로, 가능하면 let
과 const
를 사용하는 것이 권장됩니다.