본 게시물은 Effective Javascript의 내용을 재구성하여 작성되었음을 알립니다. 저작권 문제 발생시 게시물이 비공개 될 수 있습니다.
- 블록 내에서의 변수 선언은 암묵적으로 그 변수를 포함하는 함수의 맨 윗부분으로 호이스팅된다.
- 변수의 재선언은 하나의 변수처럼 처리된다.
- 혼란을 막기 위해 지역 변수 선언을 직접 호이스팅하는 것을 고려하라.
자바스크립트는 어휘적 스코프를 지원하지만, 블록 단위 스코프를 지원하지 않는다. 변수 정의는 자신을 포함한 함수에 의해 지정된다.
function isWinner(player, others) {
var highest = 0;
for (var i = 0, n = others.length; i < n; i++ ) {
var player = others[i];
if (player.score > highest) {
highest = player.score;
}
}
return player.score > highest;
}
player를 반복문의 본문 안에서 선언하려는 듯 보인다. 하지만 자바스크립트 변수는 블록이 아닌 함수에 의해 스코프가 정해지기 때문에 player 내부 선언은 이미 스코프안에 선언된 변수 player 파라미터를 재선언 하는 것 뿐이다. 반복문의 이터레이션마다 동일한 변수를 덮어쓰게 된다. 그 결과, return 선언문은 player를 함수의 원래 player 인자가 아닌 마지막 요소로 보게 된다.
자바스크립트 변수 선언의 동작과 할당의 부분으로 나누어 이해해야 한다. 자바스크립트는 암묵적으로 함수 맨 윗부분으로 선언을 끌어올리고 할당 부분은 그 자리에 그대로 둔다. 변수는 전체 함수의 스코프 안에 있지만 실제로 var 선언문이 나타난 곳에서만 할당되는 것이다.
호이스팅은 변수를 재선언할 때 혼란을 초래할 수 있다. 동일한 함수 내에서 같은 변수를 여러 번 정의하는 것은 허용되지 않는다.
function trimSections(header, body, footer) {
for ( var i = 0, n = header.length; i < n; i++ ) {
header[i] = header[i].trim();
}
for (var i =0, n = body.length; i < n; i++) {
body[i] = body[i].trim();
}
for(var i = 0, n = footer.length; i < n; i++) {
footer[i] = footer[i].trim();
}
}
trimSections 함수는 여섯 개의 지역번수(i 3개, n 3개)를 선언하지만 호이스팅으로 오직 2개만 선언되었다. 호이스팅 된 이후에는 trimSections 함수는 다음과 같이 쓰여진 셈이다.
function trimSections(header, body, footer) {
var i, n;
for ( i = 0, n = header.length; i < n; i++ ) {
header[i] = header[i].trim();
}
for ( i =0, n = body.length; i < n; i++) {
body[i] = body[i].trim();
}
for( i = 0, n = footer.length; i < n; i++) {
footer[i] = footer[i].trim();
}
}
재선언은 별도의 변수를 나타내기 때문에, 모호함을 줄이기 위해 함수의 맨 윗부분에 모든 var 선언문을 위치시키는 방식을 선언한다. 이런 스타일은 마음에 들지 않더라도, 자바스크립트의 스코프 규칙을 이해하는 것은 코드를 읽고 쓰는데 중요하다.
자바스크립트에서 블록 스코프가 지원되는 예외 상황 중 하나는 바로 exception 이다. try ... catch는 exception을 잡아 변수로 바인딩하고 catch 블록 안에서만 스코프가 적용된다.
function test ( ) {
var x = "var", result = [ ];
result.push(x);
try {
throw "exception";
} catch (x) {
x = "catch";
}
result.push(x);
return result;
}
test ( ); /// ["var", "var"]
- 블록 내에서의 변수 선언은 암묵적으로 그 변수를 포함하는 함수의 맨 윗부분으로 호이스팅된다.
- 변수의 재선언은 하나의 변수처럼 처리된다.
- 혼란을 막기 위해 지역 변수 선언을 직접 호이스팅하는 것을 고려하라.
끄읕.