JavaScript에서 함수는 일종의 데이터로 간주될 수 있으며, 변수에 할당되고 다른 함수에 중첩될 수 있습니다.
var fun = function(){ console.log("平底斜"); }
function fun(){ var n=10; function son(){ n++; } son(); console.log(n); } fun(); //11 fun(); //11
위의 두 번째 코드를 약간 수정해 보겠습니다.
var n=10; function fun(){ function son(){ n++; } son(); console.log(n); } fun(); //11 fun(); //12
차이점이 보이시나요? 코드 실행 결과를 이해하기 어렵다면 이전 블로그 게시물에서 JavaScript 범위 및 범위 체인에 대한 설명을 읽어보세요.
위 코드의 변수 n은 전역 변수이며 fun 함수를 호출하지 않고도 언제든지 재할당될 수 있습니다. 변수 n이 오염되는 것을 방지하거나 전역 변수의 오염을 줄이기 위해 함수에 n을 지역 변수로 넣어야 합니다.
function fun(){ var n=10; function son(){ n++; console.log(n); } son(); } fun(); //11 fun(); //11
son 함수를 전역적으로 직접 호출할 수 있다면 원하는 효과를 얻을 수 있습니다. 이제 son 함수는 지역 변수로 존재합니다. 전역적으로 액세스하려면 일반적으로 두 가지 방법이 있습니다.
하나는 전역 변수에 값을 할당하는 것입니다
var a; function fun(){ var n=10; a = function son(){ n++; console.log(n); } } fun(); //son() a(); //11 a(); //12
다른 하나는 return을 사용하여 값을 반환하는 것입니다
function fun(){ var n=10; return function son(){ n++; console.log(n); } } var a=fun(); a(); //11 a(); //12
위의 son() 함수는 어떤 의미에서는 모든 함수가 클로저로 간주될 수 있습니다. 클로저는 외부 함수 범위에 있는 변수에 액세스할 수 있는 함수입니다.
var a; function fun(){ var n=10; a = function son(){ n++; console.log(n); } return a(); } fun(); //11 a(); //12 a(); //13 fun(); //11 a(); //12 a(); //13
아직 위의 코드를 살짝 수정하여 실행 결과를 살펴보겠습니다. 이는 fun() 함수가 실행될 때마다 변수 n이 초기화되기 때문입니다.
클로저의 장점은 전역 변수를 줄이고 전역 오염을 방지하며 지역 변수를 메모리에 저장한다는 것입니다. 그러나 이는 장점이자 단점이기도 합니다. 코드에 클로저가 너무 많으면 메모리 누수가 발생할 수 있습니다. 클로저의 지역 변수는 가비지 수집 메커니즘에 의해 재활용되지 않으므로 수동으로 null에 할당해야 합니다(메모리 누수에 대해서는 나중에 별도의 주제가 열립니다)