인터넷에서 폐쇄에 대한 개념과 기사를 읽은 후 이 문제를 직접 정리하고 싶습니다.
Q: 폐쇄란 무엇인가요?
답변: 클로저는 JavaScript에서 외부 함수가 반환된 후에도(수명 종료) 내부 함수가 자신이 위치한 외부 함수에 선언된 매개변수와 변수에 항상 액세스할 수 있다는 의미입니다.
종료 문제가 처음 발생했습니다
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"/> <title>闭包循环问题</title> <style type="text/css"> p {background:#ccc; width: 300px; height: 100px;} </style> </head> <body> <p id="p0">段落0</p> <p id="p1">段落1</p> <p id="p2">段落2</p> <p id="p3">段落3</p> <p id="p4">段落4</p> <script type="text/javascript"> for( var i=0; i<5; i++ ) { document.getElementById("p"+i).onclick=function() { alert(i); //访问了父函数的变量i, 闭包 }; }; </script> </body> </html>
한 번도 사용해 본 적이 없다면 단락을 클릭하면 해당 단락에 해당하는 숫자 0, 1, 2, 3, 4가 팝업된다고 생각할 수도 있습니다. 그런데 사실 다 5개나 나오더라구요
온라인에서 이 문제를 논의하는 많은 블로그가 있으며 해당 번호를 팝업으로 표시할 수 있는 다양한 방법을 제시했습니다.
해결책 1: 해당 단락의 속성에 변수 i를 저장합니다
var pAry = document.getElementsByTagName("p"); for( var i=0; i< 5; i++ ) { pAry[i].no = i; pAry[i].onclick = function() { alert(this.no); } };
해결책 2: 클로저 레이어를 추가하고 i를 함수 매개변수 형식으로 내부 함수에 전달합니다
var pAry = document.getElementsByTagName("p"); for( var i=0; i< 5; i++ ) { pAry[i].no = i; pAry[i].onclick = function() { alert(this.no); } };
이로 인해 발생하는 클로저 문제에 대해 인터넷에서는 "변수 i가 함수에 포인터나 변수 주소로 저장된다"는 말이 있는데, 모두 포인터와 관련이 있습니다. . . . 그런 다음 좀 더 살펴보세요.
탐색 1, 반환 값은
대신 10입니다.
(function test() { var temp =10; for(var i=0; i< 5; i++ ){ document.getElementById("p"+i).onclick=function() { alert(temp); //访问了父函数的变量temp, 闭包 } }; temp=20; })();
2를 탐색하고 10을 한 번 반환한 다음 20을 반환합니다
(function test() { var temp =10; for( var i=0; i< 5; i++ ) { document.getElementById("p"+i).onclick=function() { alert(temp); //访问了父函数的变量i, 闭包 } if(i===1){ alert(temp); } }; temp=20; })();
1과 2의 탐색을 통해 함수와 동일한 수준의 변수가 함수 내에서 액세스되면 변수가 메모리에 상주한다는 결론을 내릴 수 있습니다. 이 변수에 액세스하면 본질적으로 변수의 주소에 액세스하게 됩니다.
그런 다음 "JS 클로저의 이 객체"에 대한 또 다른 기사를 읽었습니다. 이에 대한 문제를 계속 논의해 보겠습니다.
// js闭包this对象1 var name = 'The Window'; var object = { name : 'My Object', getNameFunc1 : function(){ // return this.name; console.log(this);//object return function(){//闭包,访问的便是全局变量的了,this指windows console.log(this);//windows return this.name; //The Window } }, getNameFunc2 : function(){ return this.name;//访问的是object }, aa:function(){ alert(22); } }; alert(object.getNameFunc1()());//弹出“The Window”
답변: 모든 함수는 호출될 때 자동으로 두 개의 특수 변수, 즉 this와 인수를 얻습니다. 이 두 변수를 검색할 때 내부 함수는 검색을 활성 개체로 지정하므로 외부 함수에서 이 두 변수에 직접 액세스하는 것은 불가능합니다.
하지만 이는 다음 코드를 사용하여 수행할 수 있습니다(외부 함수의 변수에 직접 액세스).
// js闭包this对象2 var name = 'The Window'; var object = { name : 'My Object', getNameFunc : function(){ var that = this; console.log(this);//输出的是object return function(){ console.log(this);//输出的仍然是Windows return that.name; }; } }; alert(object.getNameFunc()());//弹出“My Object”
나는 클로저에 대해 너무 많이 썼으므로 클로저의 유용성을 언급하겠습니다. 그렇지 않으면 클로저를 계속해서 다루는 것은 나쁜 사람이 될 것입니다.
function A(){ var a=1; function B(){ return a; }; return B; }; var C=A();//C取得A的子作用域B的访问接口 console.log(C());//1 C能访问到B的父级作用域中的变量a
위의 코드 중 상당수는 실제로 온라인에서 찾은 것입니다. 제가 이해한 내용과 읽는 과정을 정리한 것뿐입니다.