자바스크립트 연구 노트 - 함수(6): 범위 및 네임스페이스_기본 지식
이전 소개에서 우리는 Javascript에는 블록 수준 범위가 없고 함수 수준 범위만 있다는 것을 이미 알고 있었습니다.
function test() { // 범위
for(var i = 0; i < 10; i ) { // 범위가 아님
// 개수
}
console.log(i) // 10
}
또한 Javascript에는 명시적인 네임스페이스가 없습니다. 이는 모든 것이 전역 범위에서 정의된다는 의미입니다. 변수가 참조될 때마다 Javascript는 변수를 찾을 때까지 전체 전역 범위를 탐색합니다. 전체 전역 범위를 순회한 후에도 변수를 찾을 수 없으면 ReferenceError가 발생합니다.
이미지 설명을 입력해주세요
암시적 전역 변수
// 스크립트 A
foo = '42';
// 스크립트 B
var foo = '42'
위의 두 가지 예는 서로 다른 효과를 냅니다. 첫 번째 것은 전역 범위에서 foo 변수를 정의하고, 두 번째 것은 현재 범위에서 변수 foo를 정의합니다.
var 키워드를 사용하지 않으면 예상치 못한 결과가 발생한다는 점에 유의해야 합니다.
// 전역 범위
var foo = 42;
함수 테스트() {
// 로컬 범위
foo = 21;
}
테스트();
foo; // 21
함수 테스트에서는 foo 변수를 정의하는 데 var가 사용되지 않으므로 함수 외부의 전역 변수 foo를 덮어쓰게 됩니다. 큰 문제는 아닌 것 같지만, 수천 줄의 코드가 있으면 추적하기 어려운 버그가 될 수 있습니다.
// 전역 범위
var items = [/* 일부 목록 */];
for(var i = 0; i 하위 루프();
}
함수 하위 루프() {
// 하위 루프의 범위
for(i = 0; i < 10; i ) { // var 문이 누락되었습니다
// 놀라운 일을 해내세요!
}
}
위의 예에서 외부 루프는 처음 실행될 때 중지됩니다. 왜냐하면 하위 루프 함수 내부의 변수 i가 외부 전역 변수 i를 덮어쓰기 때문입니다. 이 오류를 방지하려면 함수 내부에 var만 추가하면 되므로 변수를 정의할 때 var 키워드를 추가하는 것을 잊지 말아야 합니다. 외부 전역 변수에 실제로 영향을 미치고 싶지 않다면 말이죠.
지역변수
Javascript의 지역 변수는 두 가지 방법으로만 생성할 수 있습니다. 하나는 var 키워드를 통해 선언하는 것이고, 다른 하나는 함수의 형식 매개변수로 생성하는 것입니다.
// 전역 범위
var foo = 1;
var bar = 2;
var i = 2;
기능 테스트(i) {
// 함수 테스트의 로컬 범위
나는 = 5;
var foo = 3;
바 = 4;
}
테스트(10);
이때, 함수 test 내부의 변수 i와 foo는 지역 변수이고, bar는 외부 전역 변수 bar를 덮어쓰게 됩니다.
호이스팅
Javascript는 변수 선언을 호이스트합니다. 즉, var 표현식과 함수 선언이 모두 범위의 맨 위에 호이스트됩니다.
바();
var bar = function() {};
var someValue = 42;
테스트();
기능 테스트(데이터) {
만약 (거짓) {
구 = 1;
} 그 밖의 {
var goo = 2;
}
for(var i = 0; i var e = 데이터[i];
}
}
위 코드를 실행하기 전에 var 표현식과 함수 테스트 선언이 상위로 승격되므로 프로그램이 정상적으로 실행되고 오류도 보고되지 않습니다.
// var 문이 여기로 이동되었습니다
var bar, someValue; // 기본값은 '정의되지 않음'
// 함수 선언도 위로 이동했습니다
기능 테스트(데이터) {
var goo, i, e; // 누락된 블록 범위가 여기로 이동됩니다
만약 (거짓) {
구 = 1;
} 그 밖의 {
구 = 2;
}
for(i = 0; i e = 데이터[i];
}
}
bar(); // bar가 여전히 '정의되지 않음'이므로 TypeError로 실패합니다
someValue = 42; // 할당은 호이스팅에 영향을 받지 않습니다
바 = 함수() {};
테스트();
Javascript에는 블록 수준 범위가 없으므로 var 표현식이 향상될 뿐만 아니라 if 구조가 덜 직관적이게 됩니다.
위의 예에서는 if 가 글로벌 변수 goo에 대해 동작하는 것처럼 보이지만 실제로는 goo 변수가 승격되었기 때문에 수정되는 로컬 변수입니다.
호이스팅 규칙을 이해하지 못하면 다음 코드가 ReferenceError를 발생시킬 것이라고 생각할 수도 있습니다.
// SomeImportantThing이 초기화되었는지 확인
if (!SomeImportantThing) {
var SomeImportantThing = {};
}
물론 위 코드는 코드가 실행되기 전에 var 표현식이 최상위로 승격되었기 때문에 오류가 없습니다.
var SomeImportantThing;
// 다른 코드에서는 여기서 SomeImportantThing을 초기화할 수도 있고 초기화하지 않을 수도 있습니다
// 거기에 있는지 확인하세요
if (!SomeImportantThing) {
SomeImportantThing = {};
}
개선 사항을 매우 자세히 설명하는 @nightire Fan Ge의 블로그 게시물 "JavaScript 이해(2)"를 추천하고 싶습니다.
이름 확인 순서
함수 범위 내에서 foo 변수에 액세스하려고 하면 Javascript는 다음 순서로 찾습니다.
현재 범위에 var foo 정의가 있는지 여부입니다.
함수 매개변수에 foo 변수가 있는지 여부.
함수 자체의 이름이 foo인지 여부.
외부 도메인으로 이동하여 첫 번째 부분부터 검색합니다.
네임스페이스
가장 일반적인 문제 중 하나는 전역 범위가 하나뿐인 Javascript로 인해 발생하는 이름 충돌입니다. 하지만 이 문제는 익명의 외부 함수를 통해 해결될 수 있습니다.
(함수() {
// 자체 포함된 "네임스페이스"
window.foo = 함수() {
// 노출된 클로저
};
})(); // 즉시 함수 실행
위 예시의 익명 함수는 표현식으로 간주되어 실행됩니다.
( // 괄호 안의 함수를 평가합니다
함수() {}
) // 그리고 함수 객체를 반환합니다
() // 평가 결과 호출
물론 구조는 다르지만 효과는 동일한 다른 방식으로 함수 표현식을 호출할 수도 있습니다.
//
를 직접 호출하기 위한 몇 가지 다른 스타일 !함수(){}()
함수(){}()
(함수(){}());
// 등등...
요약
익명의 외부 함수를 사용하여 코드를 공백으로 캡슐화하는 것이 좋습니다. 이렇게 하면 네임스페이스 충돌을 해결할 수 있을 뿐만 아니라 프로그램의 모듈화도 촉진할 수 있습니다.
또한 전역 변수를 사용하는 것은 유지 관리 비용이 많이 들고 오류가 발생하기 쉽기 때문에 좋은 방법이 아닙니다.
네임스페이스 유형, 함수, 변수, 템플릿 등은 모두 엔터티에 속합니다.
엔터티의 주요 공통점은 이름을 가질 수 있다는 것입니다. (또한 라벨에도 이름이 있을 수 있지만 개체는 아닙니다.)
네임스페이스 범위는 블록 범위, 클래스 범위, 함수 프로토타입 범위 및 함수 범위(레이블에만 유효)와 함께 범위 유형에 대한 일반적인 용어입니다. 네임스페이스 내에 선언된 이름은 네임스페이스 범위에 있습니다. 전역 이름은 암시적 전역 네임스페이스 범위에 속하는 것으로 간주됩니다.
네임스페이스의 역할은 실제로 범위이지만 단순한 범위와는 다릅니다. 동일한 네임스페이스를 여러 위치에서 여러 번 선언할 수 있지만 내용을 다시 정의할 수는 없습니다. 공간은 표준과 마찬가지로 어디에서나 매크로 정의를 사용할 수 있습니다.

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











typedef struct는 C 언어에서 구조 사용을 단순화하기 위해 구조 유형 별칭을 만드는 데 사용됩니다. 구조 별칭을 지정하여 기존 구조에 새 데이터 유형의 별칭을 지정합니다. 향상된 가독성, 코드 재사용 및 유형 확인 등의 이점이 있습니다. 참고: 별칭을 사용하기 전에 구조를 정의해야 합니다. 별칭은 프로그램에서 고유해야 하며 선언된 범위 내에서만 유효해야 합니다.

Java의 변수 예상 값 예외는 변수 초기화, null 값 사용, 지역 변수 범위 파악을 통해 해결할 수 있습니다.

JavaScript 클로저의 장점에는 변수 범위 유지, 모듈식 코드 활성화, 실행 지연 및 이벤트 처리가 포함됩니다. 단점에는 메모리 누수, 복잡성 증가, 성능 오버헤드 및 범위 체인 효과가 포함됩니다.

C++의 #include 전처리기 지시문은 외부 소스 파일의 내용을 현재 소스 파일에 삽입하고 해당 내용을 현재 소스 파일의 해당 위치에 복사합니다. 표준 입출력 함수를 포함하기 위한 #include <iostream>과 같이 코드에 필요한 선언이 포함된 헤더 파일을 포함하는 데 주로 사용됩니다.

C++ 스마트 포인터의 수명 주기: 생성: 스마트 포인터는 메모리가 할당될 때 생성됩니다. 소유권 이전: 이동 작업을 통해 소유권을 이전합니다. 해제: 스마트 포인터가 범위를 벗어나거나 명시적으로 해제되면 메모리가 해제됩니다. 객체 소멸: 가리키는 객체가 소멸되면 스마트 포인터는 유효하지 않은 포인터가 됩니다.

JavaScript에서 이 포인팅 유형은 다음을 포함합니다: 1. 전역 객체, 2. 함수 호출, 3. 생성자 호출, 5. 화살표 함수(외부 상속). 또한, 바인딩(), call() 및 apply() 메서드를 사용하여 이것이 가리키는 내용을 명시적으로 설정할 수 있습니다.

할 수 있다. C++에서는 중첩된 함수 정의 및 호출을 허용합니다. 외부 함수는 내장 함수를 정의할 수 있고 내부 함수는 범위 내에서 직접 호출할 수 있습니다. 중첩된 함수는 캡슐화, 재사용성 및 범위 제어를 향상시킵니다. 그러나 내부 함수는 외부 함수의 로컬 변수에 직접 액세스할 수 없으며 반환 값 유형은 외부 함수 선언과 일치해야 합니다.

Java의 클로저를 사용하면 외부 함수가 종료된 경우에도 내부 함수가 외부 범위 변수에 액세스할 수 있습니다. 익명의 내부 클래스를 통해 구현된 내부 클래스는 외부 클래스에 대한 참조를 보유하고 외부 변수를 활성 상태로 유지합니다. 클로저는 코드 유연성을 높이지만 익명 내부 클래스에 의한 외부 변수 참조는 해당 변수를 활성 상태로 유지하므로 메모리 누수의 위험을 인지해야 합니다.
