[JavaScript] 함수의 유효범위 (Effective range of "Function")
C언어는 절차 지향 언어라고 할수 있다. 해당 내용은 절차지향에 대한 이야기 일뿐
자바스크립트와는 많은 관련이 있진 않습니다. C를 하다 넘어 왔기 때문에
자바스크립트도 절차지향으로 보여 잘못생각하였던 부분에 대한 설명입니다.
#include
using namespace std;
int main(void)
{
printf("CPP Test\n");
show(); //show 식별자를 찾을수 없습니다. 에러
return 0;
}
void show()
{
printf("Show Call");
}
const int OpenResult(int flag)
{
}
// 해당 호출이 불가능해지기 때문에
// 실제 사용시에는
// 이 처럼 코드 상단에 미리 선언을 하고 원형을 하단에 작성한다.C 의경우
#include
using namespace std;
// 절차 선언
void show();
int main(void)
{
printf("CPP Test\n");
show();
return 0;
}
void show()
{
printf("Show Call");
}
의 형태로 지원되어야 한다. 절차지향
자바스크립트 또한 그럴것이라 생각 하였지만 실제 JS에서 유효범위는 생각과는 달랐다.
function external(){
typeof Internal ==='function' ? console.log("Internal exist") : console.log("Internal not exist");
function Internal (){};
typeof Internal ==='function' ? console.log("Internal exist") : console.log("Internal not exist");
window.Internal === undefined ? console.log('Internal is not window exist' ) : console.log('Internal window exist');
window.external === undefined ? console.log('external is not window exist') : console.log('external window exist');
}
external();
결과
Internal exist
Internal exist
Internal is not window exist
external window exist
1번째에
typeof Internal ==='function 부분에서 exist로 넘어가는것으로 보아
절차적으로 코드가 생성되는것으로 보였지만
자바스크립트의 유효범위는 블록이 아니라 함수에 의에 정의된다고 할수있다.
여기까지보면 뭔가 큰 차이가 안 느껴져서 자바스크립트의 Scope Chain 은 Function 이라는 예제를 하나 더 들수 있다.
C의 경우
void show()
{
printf("Show Call");
for (int i = 0; i < 5; i++)
{
int b = 10;
}
printf("B is %d", b);
}
// 와 작성시 이미 printf b 에서 컴파일 하기도전에 validation 에 걸립니다. b가 정의되어있지 않습니다.
// C,C++에서는 Scope Chain 은 Block Scope를 가진다는 것을 알수 있습니다.
JavaScript 의 경우
function show()
{
for (var i=0;i<5;i++)
{
var b = 10;
}
console.log("B is ",b);
}
show();
// 결과
// B is 10
자바 스크립트의 Scope Chain 은 위와 같이 Function 을 가지게됩니다.
이에 대해서 JS 작성시 실수하였던 점이
for(var i=0;i<10;i++)
{
for(var j=0;j<10;j++)
{
for(var i=0;i<5;j++)
{
}
}
}
해당 식의 코드를 한번 짤일이 있었는데 디버그 하다가 애를 먹었던적이 있습니다.
처음 i 0 ~을 돌다가 3번째 for문에서 i가 4인 채로 끝나기 때문에 자기 밖으로나가면 i2가 된상태로 돌아야하지만
i4인채로 끝나서
첫번째 포문에서 i 0 1,2,3 부분이 건너 뛰고 바로 4로 넘어가는 현상이 생겼습니다.
js에서는 function Scope Chain 을 가지기 때문에 해당 부분에 유의 하여야 합니다.
최근 ES스펙이 오름에 따라서 let변수가 해당 C,C++의 block scope 를 가지게 도와주지만 해당 내용은 뒤에 작성하도록 하겠습니다.