>  기사  >  웹 프론트엔드  >  JavaScript 변수 범위 및 closure_javascript 기술

JavaScript 변수 범위 및 closure_javascript 기술

PHP中文网
PHP中文网원래의
2016-05-16 18:48:311015검색

범위 JavaScript의 변수 범위는 함수에 따라 나누어져 있으며, 그 특징을 빠르게 이해할 수 있도록 예제를 통해 보여드리겠습니다.

예 1:

<script type="text/javascript"> 
var i = 1; 
// 弹出内容为 1 true 的提示框 
alert(window.i + &#39; &#39; + (window.i == i)); 
</script>

분석:
전역적으로 정의된 변수는 실제로는 창 개체의 속성입니다.
위의 예에서 볼 수 있듯이 전역 변수를 정의하면 창 개체가 해당 속성을 생성합니다. 코드에서 이 속성이 생성되지 않도록 하려면 아래 예를 참조하세요.
예 2:

<script type="text/javascript"> 
var document = 1; 
window.onload = function(){ 
alert(document); 
} 
// 弹出内容为 1 的提示框 
alert(window.document); 
</script>

보고 싶지 않은 상황입니다.

<script type="text/javascript"> 
function test(){ 
var document = 1; 
window.onload = function(){ 
alert(document); 
} 
} 
test(); 
// 弹出内容为 [object] 的提示框 
alert(window.document); 
</script>

코드를 더 간결하게 만들기 위해, 다음과 같이 할 수 있습니다:

<script type="text/javascript"> 
(function(){ 
var document = 1; 
window.onload = function(){ 
alert(document); 
} 
})(); 
// 弹出内容为 [object] 的提示框 
alert(window.document); 
</script>

분석:
이런 형태의 익명 메소드 실행은 주류 JavaScript 프레임워크에서 흔히 볼 수 있습니다. 이렇게 하면 창 객체의 불필요한 속성 생성을 방지하고 충돌 가능성을 줄일 수 있습니다.
예 3:

<script type="text/javascript"> 
(function(){ 
if(&#39;1&#39; == &#39;1&#39;){ 
var i = 1; 
} 
// 弹出内容为 1 的提示框 
alert(i); 
})(); 
</script>

분석:
변수의 범위는 {} 블록이 아니라 전체 함수입니다.
예 4:

<script type="text/javascript"> 
var i = 1; 
// 弹出内容为 1 的提示框 
alert(i); 
var i = 2; 
// 弹出内容为 2 的提示框 
alert(i); 
</script>


분석:
변수를 재정의할 수 있는데, 이는 다른 많은 언어에서는 작동하지 않기 때문에 약간 이상해 보입니다.
예 5:

<script type="text/javascript"> 
function test(){ 
i = 1; 
} 
test(); 
// 弹出内容为 1 的提示框 
alert(window.i); 
</script>

분석:
초기화되지 않은 변수에 값이 할당되면 이 변수는 전역 변수로 사용됩니다.

예 6:

<script type="text/javascript"> 
window.onload = function(){ 
var i = 1; 
function test(){ 
alert(i); 
} 
// 弹出内容为 1 的提示框 
test(); 
} 
</script>

분석:
내부 함수는 외부 함수의 변수에 접근할 수 있는데, 이는 클로저라는 새로운 개념으로 이어집니다.
클로저
클로저란 간단히 말해서 함수 A가 종료되더라도 내부 함수 B가 A에 정의된 변수에 접근할 수 있는 함수 A입니다. 사례를 통해 알아보겠습니다.
예 7:

<script type="text/javascript"> 
window.onload = function(){ 
var i = 1; 
window.onunload = function(){ 
alert(i); 
} 
} 
</script>

분석:
전체 페이지가 로드되면 onload 이벤트가 트리거됩니다. 이 onload 이벤트 메소드는 창의 onunload 이벤트에 대한 메소드를 등록합니다. 이 메소드 onload 이벤트 메소드에 선언된 변수가 사용되며, 이때 onload 이벤트 메소드가 종료됩니다. 이때 클릭하여 창을 닫으면 내용이 1인 프롬프트 상자가 팝업되어 onunload 이벤트를 나타냅니다. 메소드가 onload 이벤트 메소드에 선언된 변수를 성공적으로 호출했습니다.
클로저의 특성을 더 자세히 이해하려면 다음 예를 살펴보세요
예 8:

<script type="text/javascript"> 
function initX(oarg){ 
// 定义一个变量 
var x = oarg; 
// 定义一个显示变量的方法 
var funGet = function(){ 
alert(x); 
} 
// 定义一个对变量进行修改的方法 
var funSet = function(iarg){ 
x = iarg; 
} 
// 返回这两个方法 
return [funGet,funSet]; 
} 
// 运行一个方法实例,返回值为包含 get 和 set 方法的数组 
var funArr = initX(1); 
// 得到 get 方法 
var funGet = funArr[0]; 
// 得到 set 方法 
var funSet = funArr[1]; 
// 运行 get 方法,显示initX方法实例内的 x 变量,结果为 1 
funGet(); 
// 运行 set 方法,对initX方法实例内的 x 变量进行赋值 
funSet(2); 
// 运行 get 方法,显示initX方法实例内的 x 变量,结果为 2 
funGet(); 
</script>

분석:
내부 함수가 외부 함수에서 정의한 변수를 호출하는 경우 , 실제로 참조는 이 변수의 메모리 블록에 대한 것이므로 내부 함수를 호출할 때 참조된 변수 값은 현재 변수의 실제 내용입니다.
폐쇄 기능은 강력하지만, 주의하지 않으면 문제가 발생할 수도 있습니다. 아래 예를 참조하세요.
예제 9:

<button id="main">run</button> 
<script type="text/javascript"> 
(function(){ 
var obj = document.getElementById("main"); 
var funArr = [&#39;onclick&#39;,&#39;onkeypress&#39;]; 
for(var i=0; i<funArr.length; i++){ 
var temp = funArr[i]; 
obj[temp] = function(){ 
alert(temp); 
} 
} 
})(); 
</script>

코드 작성의 원래 의도는 ID가 main인 버튼에 대한 클릭 이벤트와 키 이벤트를 등록하는 것입니다. 이벤트 내용은 프롬프트 상자를 팝업하는 것입니다. 각각 이벤트 이름으로. 그런데 결과가 조금 이상합니다. 두 이벤트의 프롬프트 상자는 모두 onkeypress입니다. 닫힘 원칙에 따라 주의 깊게 분석하면 두 이벤트 메서드가 호출될 때 임시 변수가 콘텐츠를 가리킨다는 것을 알 수 있습니다. 이 문제를 해결하려면 다음과 같이 수정하면 됩니다.

<button id="main">run</button> 
<script type="text/javascript"> 
(function(){ 
var obj = document.getElementById("main"); 
var funArr = [&#39;onclick&#39;,&#39;onkeypress&#39;]; 
for(var i=0; i<funArr.length; i++){ 
(function(){ 
var temp = funArr[i]; 
obj[temp] = function(){ 
alert(temp); 
} 
})(); 
} 
})(); 
</script>

for 루프의 코드를 함수에 넣어 각 루프가 함수 인스턴스를 생성하고 함수 인스턴스가 실행되도록 합니다. funArr 배열에 각 값을 기록하면 위에서 발생한 문제를 피할 수 있습니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.