JavaScript

[JavaScript] Closure_클로저

vhxpffltm 2019. 5. 27. 21:58

이 내용은 '생활코딩'에서 공부한 내용을 정리한 글이다. 

자세한 내용은 https://www.opentutorials.org/course/743 이곳에서 확인할 수 있다. 

모든 내용의 출처는 이곳이다. 다른 언어를 알고있는 상태로 공부한 내용이다.

 

 

대부분의 참고자료 및 설명을 참고하면서 클로저는 C언어의 포인터와 같은 맥락이라고 생각하면 좋다. 즉, 클로저는 자바스크립트에서 꽃과 같은 중요한 내용이며 어려울 수 있다.

 

우선 클로저를 이해하기 위해서 알아야 할 내용으로 변수의 유효범위, 외부함수내부함수가 있다.

 

변수의 유효범위는 전역, 지역으로 나누어지며 이전 게시글을 참고하자.

 

간단하게, 내부함수는 함수 안에 함수가 있는것이고, 외부함수는 제일 밖에 있는 함수를 말한다.

 

클로저는 이 내부함수가 외부함수의 맥락에 접근할 수 있는것을 의미하고 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미한다.

 

본 코드를 보기전에 간단한 코드를 보면,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function makePrinter() {
    var outer_name = "김철수";
 
    function printName() {
        var inner_name = "김영희";
        console.log(global_name);
        console.log(outer_name);
        console.log(inner_name);
    }
 
    return printName;
}
 
var print = makePrinter();
//여기서 외부함수는 종료!!!
 
print();
 

위 코드에 외부함수와 내부함수가 정의되어 있고, print()를 호출하였을때, outer_name으로 '김철수'가 출력됨을 확인 할 수 있다. 아래에도 이 예시가 있다.

클로저는 자신을 포함하고 있는 외부 함수의 인자, 지역변수 등을 외부 함수가 종료된 후에도 사용할 수 있으며. 이러한 변수를 자유 변수(free variable) 하고 한다.

 

출처 : https://offbyone.tistory.com/135    https://unikys.tistory.com/309

 

*위의 참고사이트에서 자세하게 내용을 공부하고 알아볼 수 있다*

 

아래의 실습코드와 주석을 참고바란다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <script>
        function out() {
            var string = "C언어 language";
            function In (){
                //var string = 'C++ language';
                document.write(string);
                //In을 포함하고 있는 string이라는 변수를 찾는다.
                //외부함수의 지역변수에 접근할 수 있다. 이것이 클로저.
            }//in 은 내부함수
            In();
        }// out은 외부함수
        out();
 
 
        document.write("<br />" + "<br />");
 
        function out2() {
            var str = "C++_vector";
            return function () {
                document.write(str);
            }// 내부함수를 return, 이 함수는 종료됨. 
        }
        var In2 = out2(); // out2 외부함수를 실행한 결과를 In2변수에 대입
        In2(); //함수호출 -> 이미 out2라는 함수는 실행되서 끝이 남...
        // 이것을 실행하면 이미 종료된 외부함수에 존재하는 str이 실행됨.
        // 종료된 외부함수의 접근이 가능하게됨... 이것이 클로저
 
        document.write("<br />" + "<br />");
 
 
        function f_movie(name) {//지역변수, private변수의 맥락
            return {
                get_name: function () {
                    return name//name은 첫번째 
                }, // 속성이 타이틀
                set_name: function (_name) {
                    name = _name;
                    //내부변수의 값이 바뀐다.
                }
                //객체안에 함수가 있다. (내부함수소속이 객체의 소속이다.)
            }// 객체를 리턴
        }
        var ghost = f_movie("ghost in the shell");
        var mat = f_movie("matrix");
        document.write(ghost.get_name() + "<br />");
        document.write(mat.get_name() + "<br />");
 
        ghost.set_name("play on game");
 
        document.write(ghost.get_name() + "<br />");
        document.write(mat.get_name() + "<br />");
        //
        //1. 클로저는 객체의 메소드에서도 사용가능, 함수의 리턴값으로 객체를 반환, 이 객체는 get_name과 set_name을 가짐,
        //이 메소드들은 외부함수 f_movie의 인자값으로 전달된 name을 사용
        //2. 동일한 외부함수 안에서 만들어진 내부함수나 메소드는 외부함수의 지역변수를 공유, set_name을 바꾸고 get_name이 바뀐것으로 확인
        //3. 하지만 같은 외부함수를 공유하고 있는 ghost와 mat의 get_name값은 다르다. 외부함수가 실행될때마다 새로운 지역변수(name)을 포함하는 클로저가 생성되기 떄문
        // 즉, ghost와 mat은 독립된 객체가 된다!!
        //4. 외부함수(f_movie)의 지역변수(name)은 return으로 정의된 객체의 메소드만 접근 할 수 있는 값, C++의 private 클래스처럼 생각. 
    </script>
    <h1>클로저는 내부함수가 외부함수의 맥락에 접근할 수 있는것..?</h1>
    <h1>클로저는 외부함수(포함하고 있는)의 변수에 접근할 수 있는 내부 함수</h1>
    <h1></h1>
</body>
</html>
 
 

 

'JavaScript' 카테고리의 다른 글

[JavaScript]전역객체 와 this 키워드  (0) 2019.05.27
[JavaScript]생성자와 new  (0) 2019.05.27
[Javascript] 함수의 호출(apply)  (0) 2019.05.27
[JavaScript] arguments 객체  (0) 2019.05.19
[JavaScript] 변수의 유효범위  (0) 2019.05.19