디지털 컨버전스/Java Script

[Javascript] 클로저(closure)

gimyeondong 2020. 4. 14. 11:51

 

배열에 엘리먼트, 함수도 담을 수 있음

 

getElementsByClassName

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script>
            window.onload = function(){
                var btns = document.getElementsByClassName("btn");
                
                for(var i =0;i<btns.length;i++){
                    btns[i].onclick =function(){
                        alert("Pop!");
                    };
                }
            }
        </script>
    </head>
    <body>
        <button class="btn">Button1</button>
        <button class="btn">Button2</button>
        <button class="btn">Button3</button>
        <button class="btn">Button4</button>
        <button class="btn">Button5</button>
    </body>
</html>

 

 


cf] for문을 쓰지 않고 바로 이벤트를 주는경우 실행되지 않음!

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script>
            window.onload = function(){
                var btns = document.getElementsByClassName("btn");
                btns.onclick= function(){
                    alert("POP!");
                }
                
//                for(var i =0;i<btns.length;i++){
//                    btns[i].onclick =function(){
//                        alert("Pop!");
//                    };
//                }

            }
        </script>
    </head>
    <body>
        <button class="btn">Button1</button>
        <button class="btn">Button2</button>
        <button class="btn">Button3</button>
        <button class="btn">Button4</button>
        <button class="btn">Button5</button>
    </body>
</html>

 

 

엘리먼트(버튼)에는 이벤트를 줄수 있지만

 

배열에다가는 이벤트를 줘도 발생되지 않음


버튼 번호대로 pop에 출력하고 싶을 때

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script>
            window.onload = function(){
                var btns = document.getElementsByClassName("btn");

                
                for(var i =0;i<btns.length;i++){
                    btns[i].onclick =function(){
                        alert("Pop!"+i);
                    };
                }

            }
        </script>
    </head>
    <body>
        <button class="btn">Button1</button>
        <button class="btn">Button2</button>
        <button class="btn">Button3</button>
        <button class="btn">Button4</button>
        <button class="btn">Button5</button>
    </body>
</html>

 

 

자바에서 하듯이 for문 안에 변수i로 표기할 경우, 모든 버튼에서 5로 출력됨 


자바에서 쓰레드를 만들 때의 Call-back패턴 생각해보자

 

for문이 다 돌고

 

onclick 클릭 했을 때의 함수실행 

그 때 할당된 i가 출력되면 5

 

자바스크립트에서 클로저(closure)를 허용

 

자바스크립트는 callback 안에서 지역변수 사용

(자바에서는 상수처리(파이널)를 하거나 멤버필드로 빼야 쓸 수 있음)

 

지역변수를 사용하는 특정 구역에서 함수를 생성하면

함수는 자신이 생성된 시점에 외부 환경을 기억한다.

- 지역변수임에도 내부에서 특정 함수가 그 지역변수를 사용하면 사라지지 않음 (자바에서는 지워짐)


해결방법 1. 포괄적 해결 방법

IIFE ( Immediately Invoked Function Expressions ) : 즉각적으로 실행되는 함수 표현

클로저를 해결하기 위해 만들어지진 않았지만, 상황 해결 가능

 

// 자바 - 익명 인스턴스 기법
// 1회용으로 쓰고 버려짐

new Thread().start()

 

함수를 만든 자리에서 바로 call하는 표현 방법 : 이피

스크립트계열 언어에 허용되는 문법들...

        (function(){
            alert("Pop");
        })();
        (function(num1,num2){
            return num1+num2;
        })(10,20);
            var result =  (function(num1,num2){
                return num1+num2;
            })(10,20);

            console.log(result);

IIFE 와 클로저

 

                for(var i =0;i<btns.length;i++){
                    btns[i].onclick = // 함수가 들어가야함
                }
                for(var i =0;i<btns.length;i++){
                    btns[i].onclick = function(){
                        return function(){}
                    };
                }
                //위의 함수가 들어감
                for(var i =0;i<btns.length;i++){
                    btns[i].onclick = (function(){
                        return function(){}
                    })();
                }
                // IIFE로 감싸져서 리턴함수가 들어감

 

 

                for(var i =0;i<btns.length;i++){
                    btns[i].onclick = (function(){
                        return function(){
                            alert("Pop!"+i);//밖의 i를 기억
                        };
                    })();
                }
                for(var i =0;i<btns.length;i++){
                    btns[i].onclick = (function(p){
                        return function(){
                            alert("Pop!"+p); //반복될때 새로운 p 생성
                        };
                    })(i);
                }

 

 

 


https://meetup.toast.com/posts/86

 

자바스크립트의 스코프와 클로저 : TOAST Meetup

자바스크립트의 스코프와 클로저

meetup.toast.com


this : 자기자신

            window.onload = function(){
                //                var btns = document.getElementsByClassName("btn");
                //                for(var i =0;i<btns.length;i++){
                //                    btns[i].onclick = (function(p){
                //                        return function(){
                //                            alert(btns[p].innerHTML);
                //                        };
                //                    })(i);
                //                }

                var btns = document.getElementsByClassName("btn");

                for(var i =0;i<btns.length;i++){

                    btns[i].onclick = function(){
                        alert(this.innerHTML);
                    };
                }
            }

this를 쓸수 없는 상황에서는 이피사용



https://blueshw.github.io/2018/03/12/this/

 

[javascript] this는 어렵지 않습니다.

this 는 어렵지 않습니다. this 를 어렴풋이 알고는 있지만, 누가 물어봤을때 제대로 대답해 줄수 있도록 정리해보겠습니다. 많은 개발자들이 javascript 의 this 를 혼란스러워합니다. 사실 개념 자체가 어렵진 않습니다. 다만, 다른 프…

blueshw.github.io