변수의 범위에 대해 C, Java 등의 언어에서는 "블록 범위" 방식을 채택합니다. 이와 달리 JavaScript는 "함수 범위" 접근 방식을 채택합니다. 즉, 변수의 범위는 변수가 위치한 함수에 의해서만 결정되며 if 및 for와 같은 논리 블록과는 아무 관련이 없습니다. 예를 들어 다음 예에서는 C, Java 및 기타 언어와 다른 JavaScript의 동작을 보여줍니다.
C 및 Java와 같은 "블록 범위" 언어에서는 if 문 및 for 문과 같은 논리 블록이 끝난 후 이러한 논리 블록 내에 정의된 변수가 소멸됩니다. JavaScript는 다릅니다. 변수가 함수 내에 정의되어 있으면 전체 함수 내의 모든 코드는 변수가 정의되기 전의 코드라도 해당 변수에 액세스할 수 있습니다.
위의 예에서 in 함수가 정의된 적이 없으면 console.log(a)는 ReferenceError를 발생시킵니다. 함수에서 a가 정의되면 정의가 a 변수 호출 명령문 뒤에 있더라도 a에 대한 호출은 적법한 연산입니다(변수 정의가 호출 명령문 다음에 발생하면 변수의 a 변수 값은 호출 문이 정의되지 않았습니다). 실제로 함수 내에서 var 키워드로 정의된 모든 변수에 대해 정의 작업은 함수의 시작 부분으로 이동됩니다(할당 작업은 var가 정의된 줄에 계속 남아 있음). 이를 JavaScript에서는 호이스팅이라고 합니다. 예를 들어 위 코드는 다음과 동일합니다.
변수 범위 체인
JavaScript의 변수 저장에 문의하시면 JS의 "함수 범위"와 호이스팅에 대해 잘 이해할 수 있습니다. 전역 객체나 함수 호출 객체에 변수가 저장되기 때문에, 함수에 변수를 정의하면 함수 내 어디에 변수가 정의되어 있든 함수 호출 객체에는 이 값을 갖는 함수 호출 객체가 필연적으로 존재하게 됩니다. . 변수와 이름이 같은 속성입니다. 이러한 방식으로 함수 내 어디에서나 변수에 액세스할 수 있습니다.
함수 호출과 관련하여 JavaScript에는 더 흥미로운 개념이 있습니다. 즉, 변수의 범위 체인입니다. 변수는 전역 개체 또는 함수 호출 개체에 저장되기 때문에 변수에 액세스할 때 여러 곳에서 액세스할 수 있습니다. 값을 가져옵니다. 다음 코드를 예로 들어 보겠습니다.
위 코드의 level-2 함수 내에서 x 변수에 접근하려고 하면 프로그램은 3개의 객체, 즉 level-2 함수를 호출하는 데 사용된 함수 호출 객체, Function call에서 해당 속성 값을 검색할 수 있습니다. 레벨 1 함수를 호출하는 데 사용되는 객체 및 전역 객체 - 함수 정의의 중첩 관계를 기반으로 JavaScript는 전역 객체와 함수 호출 객체로 구성된 객체 체인을 생성합니다. 변수에 접근할 때 프로그램은 접근문에 가장 가까운 객체부터 검색을 시작합니다. 검색이 없으면 전역 객체가 나올 때까지 객체 체인의 상위 수준에 있는 객체에서 검색이 계속됩니다.
이 개체 체인은 변수의 범위와 관련되어 있으므로 "범위 체인"이라고도 합니다.
일시적으로 범위 체인을 변경하고 범위 체인 앞에 개체를 삽입해야 하는 경우(액세스된 첫 번째 함수 개체로) with 문을 사용할 수 있습니다.
그러나 JavaScript 엄격 모드에서는 with 문이 비활성화됩니다. 비엄격 모드에서도 with 문을 사용하지 않는 것이 좋습니다.