
자바스크립트는 지역 블록안에 함수를 선언하는 표준이 없다. 다음 함수의 맨 윗부부에 함수 선언문을 넣는 방법은 관례적이고 완벽히 정확하다
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;
}
이방법은 스코프에 대한 궁금증을 해결해준다. 내부 변수는 무조건 지역변수로 바인딩되고, 할당만 조건적으로 실행된다. 따라서 결과 값은 어떤 환경에서든 동일하다.