1. 자바스크립트 범위
자바스크립트 변수에는 실제로 전역 변수와 함수 내부 변수라는 두 가지 범위만 있습니다. 함수 내 어디에서나 정의된 변수의 범위(var 범위)는 전체 함수 본문입니다.
전역 변수: 창 개체 아래의 개체 속성을 나타냅니다.
범위 분할: 컨텍스트를 기준으로 블록이 아닌 기능별로 구분됩니다.
두 가지 강조점:
1. 동일한 범위에서 JavaScript는 변수의 반복 정의를 허용하며 후자의 정의는 이전 정의를 덮어씁니다.
2. 함수 내부에 var 키워드를 추가하지 않고 변수를 정의하면 기본적으로 전역 변수가 됩니다.
var scope="global"; function t(){ console.log(scope); //"global" scope="local" console.log(scope); //"local" } t(); console.log(scope); //"local" var scope="global"; function t(){ console.log(scope); //"undefined" var scope="local" console.log(scope); //"local" } t(); console.log(scope); //"global"
변수 분해 과정에서는 로컬 범위를 먼저 검색한 후 상위 범위를 검색합니다. 첫 번째 코드의 함수에는 변수 범위가 정의되어 있지 않으므로 상위 범위(전역 범위)를 검색하여 해당 값을 출력합니다. 그러나 변수 범위는 두 번째 코드의 함수에서 정의되므로(변수가 콘솔 이후 또는 이전에 정의되었는지 여부에 관계없이 변수 범위는 이 범위에 있는 것으로 간주됩니다) 더 이상 상위 범위가 아닙니다. 검색하면 범위가 직접 출력됩니다. 하지만 안타깝게도 지역 변수 i에는 현재 값이 할당되지 않아 출력이 정의되지 않습니다.
//所以根据函数作用域的意思,可以将上述第二段代码重写如下: var scope="global"; function t(){ var scope; console.log(scope); scope="local" console.log(scope); } t();
함수 범위의 특성으로 인해 지역 변수는 항상 함수 본문 전체에 정의됩니다. 변수 선언을 함수 본문의 맨 위로 "진행"할 수 있습니다.
var b; //第1步 function fun(){ b = "change"; } alert(b);//输出undefined,由于第1步只定义未赋值 var b; //第1步 function fun(){ b = "change"; } fun(); //调用上述函数 alert(b); //输出change
var를 사용하여 변수를 선언하는 경우 생성된 속성은 구성할 수 없습니다. 즉, 삭제 연산자를 통해 삭제할 수 없습니다.
2. 스코프 인스턴스
<html> <head> <script type="text/javascript"> function buttonInit(){ for(var i=1;i<4;i++){ var b=document.getElementById("button"+i); b.addEventListener("click",function(){ alert("Button"+i);},false); } } window.onload=buttonInit; </script> </head> <body> <button id="button1">Button1</button> <button id="button2">Button2</button> <button id="button3">Button3</button> </body> </html>
등록 이벤트가 종료되면 i의 값은 4입니다. 버튼을 클릭하면 이벤트 함수는 function(){ Alert("Button" i);} 에 따르면 이 익명 함수에는 i가 없습니다. 스코프 체인이므로, ButtonInit 함수에서 찾으면 됩니다. 이때 i의 값은 4이므로 "button4"가 뜹니다.
3. 자바스크립트 종료
js에서 클로저는 주로 js의 여러 다른 기능(스코프 체인, 가비지(메모리) 재활용 메커니즘, 함수 중첩 등)과 관련됩니다.
1. 스코프 체인(Scope Chain): 간단히 말해서, 스코프 체인은 함수를 정의할 때 사용되는 변수의 값을 찾기 위해 생성되는 인덱스입니다. 그 내부 규칙은 함수 자체의 지역 변수를 맨 앞에 두는 것입니다. 두 번째로 자신의 부모 함수에 변수를 더 높은 수준의 함수에 넣고 전역 개체까지 계속 배치합니다. 함수에서 변수 값을 쿼리해야 하는 경우 js 인터프리터는 앞의 로컬 변수부터 시작하여 범위 체인을 검색합니다. 해당 변수가 없으면 다음 수준 체인에서 검색합니다. . 변수가 발견되면 더 이상 진행하지 마십시오. 필요한 변수가 마지막에 발견되지 않으면 인터프리터는 정의되지 않은 값을 반환합니다.
2. Javascript의 가비지 수집 메커니즘: Javascript에서 객체가 더 이상 참조되지 않으면 해당 객체는 GC에 의해 재활용됩니다. 두 객체가 서로를 참조하고 더 이상 제3자가 참조하지 않는 경우, 서로를 참조하는 두 객체도 재활용됩니다. 함수 a는 b에 의해 참조되고 b는 a 외부의 c에 의해 참조되기 때문에 함수 a는 실행 후 재활용되지 않습니다. 클로저를 생성합니다. 이 변수는 내부 함수가 호출되지 않는 경우에만 재활용되며 클로저에서 참조하는 변수는 시작 시 재활용되지 않습니다.
3. 클로저를 사용하면 중첩된 함수 구조가 작동할 수 있습니다
4. js 클로저를 사용하여 루프 바인딩 이벤트 구현
<html> <head> <title>闭包</title> </head> <body> <ul id="list"> <li>第1条记录</li> <li>第2条记录</li> <li>第3条记录</li> <li>第4条记录</li> <li>第5条记录</li> <li>第6条记录</li> </ul> <script type="text/javascript"> function tt(nob) { this.clickFunc = function() { alert("这是第" + (nob + 1) + "记录"); } } var list_obj = document.getElementById("list").getElementsByTagName("li"); //获取list下面的所有li的对象数组 for (var i = 0; i<= list_obj.length; i++){ console.log(list_obj[i]) list_obj[i].onmousemove = function(){ this.style.backgroundColor = "#cdcdcd"; } list_obj[i].onmouseout = function() { this.style.backgroundColor = "#FFFFFF"; } //list_obj[i].onclick = function() { // alert("这是第" + i + "记录"); //不能正常获取 alert出来的都是:“这是第6记录” //} var col = new tt(i); //调用tt函数 list_obj[i].onclick = col.clickFunc; //执行clickFunc函数 } </script> </body> </html>
이상 내용이 이 글의 전체 내용입니다. 자바스크립트 프로그래밍을 배우시는 모든 분들께 도움이 되었으면 좋겠습니다.