반응형

자바스크립트는 함수 활용 능력에 따라 고수와 하수로 나눌 수 있다.

 

다음의 내용들은 중요하지만 필수는 아니다.
하지만 잘 이해하고 활용하면 자바스크립트의 고수가 될 수 있을 것이다.

    - 이름을 부여하는 인자로 코드 가독성 높이기

    Named Function Parameter
    호출 시 이름을 명시적으로 지정할 수 있는 인자

    장점
    ○ 인수가 많아도 코드 의미 해석이 쉬움
    ○ 생략 가능한 인자를 표현하기 쉬움
    ○ 인자의 순서를 자유롭게 변경가능

    단점으로 코드가 장황하게 나열되는 것이나 다음과 같은 상황에서는 유효한 방법이다.
    ○ 원래 인자의 수가 많음.
    ○ 생략 가능한 인자가 많아 생략할 패턴도 다양함.

 

    사용 시 문맥에 따라 구분하여 사용을 권장한다.

 

namedArgstest.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>이름 부여 인수</title>
</head>
<body>
<pre>
<script type="text/javascript">
function triangle(args) {
    if (args.base == undefined) { args.base = 1; }
    if (args.height == undefined) { args.height = 1; }
    return args.base * args.height / 2;
}
 
document.writeln(triangle({ base:5, height:4 }));
</script>
</pre>
</body>
</html>
cs

 

함수의 인자도 함수(Higher-order function)

함수를 인자로 받거나 함수를 결과로 반환하는 함수를 지칭한다.

 

higherOrder1test.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>고계함수</title>
</head>
<body>
<pre>
<script type="text/javascript">
function arrayWalk(data, f) {
    for (var key in data) {
        f(key, data[key]);
    }
}
 
function showElement(key, value) {
    document.writeln(key + ':' + value);
}
 
var ary = [124816];
arrayWalk(ary, showElement);
</script>
</pre>
</body>
</html>
cs

 

사용자 정의 함수를 다른 것으로 넣을 수도 있다.(가장 이유)

higherOrder2test.html

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
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>고계 함수</title>
</head>
<body>
<pre>
<script type="text/javascript">
function arrayWalk(data, f) {
    for (var key in data) {
        f(key, data[key]);
    }
}
 
var result= 0;
function sumElement(key, value) {
    result += value;
}
 
var ary = [124816];
arrayWalk(ary, sumElement);
document.writeln('합계치:' + result);
</script>
</pre>
</body>
</html>
cs

 

위의 예제에서 arrayWalk함수의 내용은 변경하지 않았다는 것에 주목한다.

범위를 함수로 정의하고 세부적인 내용을 사용자가 알아서 함수로 정의하여 사용이 가능.

(어마어마 하군...)

 

일회용 함수는 익명으로

anonymoustest.html

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
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>고계함수</title>
</head>
<body>
<pre>
<script type="text/javascript">
function arrayWalk(data, f) {
    for (var key in data) {
        f(key, data[key]);
    }
}
 
var ary = [124816];
arrayWalk(
    ary, 
    function (key, value) {
        document.writeln(key + ':' + value);
    }
);
</script>
</pre>
</body>
</html>
cs

위의 기법은 함수 호출 코드에 함수를 직접 정의하여 전달하는 방식이다.

코드가 읽기 쉬워지고 함수 관계가 이해하기 쉽다.

이름을 지정하지 않으므로 의도치 않는 이름 중복을 피할 있다.

이 기법은 Ajax를 사용할 때 함수를 정의하는 방법으로 많이 사용된다.

중요하다.

 

스코프 체인

    자바스크립트는 실행 내부적으로 Global객체를 생성함.

    개발자가 의식할 필요는 없음

    글로벌 객체는 글로벌변수나 글로벌함수를 관리하기 위한 편의적인 객체이며

    글로벌 변수와 글로벌 함수는 글로벌 객체의 프로퍼티이다.

    지역변수는 Activation 객체(또는 Call객체) 프로퍼티이다.

 

    Call객체: 함수 호출 마다 내부에서 자동으로 생성되는 객체(지역변수 관리)

         - arguments역시 Call객체의 프로퍼티.

 

    스코프 체인은 글로벌 객체-Call객체를 생성 순서대로 연결한 리스트이며

    이를 이용하여 변수의 스코프를 이해하고 관리할 있다.

 

         - 자바스크립트 동작 - A함수 호출 - B함수 호출

         - 글로벌객체생성 - A함수 Call객체 - B함수 Call객체

 

scopeChaintest.html

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
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>스코프체인</title>
</head>
<body>
<pre>
<script type="text/javascript">
var  y = 'Global';
function outerFunc(){
  var y = 'Local Outer';
 
  function innerFunc(){
    var z = 'Local Inner';
    document.writeln(z);
    document.writeln(y);
    document.writeln(x);
  }
 
  innerFunc();
}
 
outerFunc();
</script>
</pre>
</body>
</html>
cs

 

코드에서 변수를 검색 스코프 체인의 시작(가장 안쪽의 함수) Call객체부터 글로벌 객체 까지 순서대로 검색(안에서 밖으로 이름을 찾음)

변수명이 중복되었을 경우 위와 같은 개념을 알고 있어야 해결이 가능하다.

 

클로저(Closure)

지역변수를 참조하는 함수 안의 함수

closure1test.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>클로져</title>
</head>
<body>
<pre>
<script type="text/javascript">
function closure(init) {
  var counter = init;
 
  return function() {
    return ++counter;
  }
}
 
var myClosure = closure(1);
document.writeln(myClosure());
document.writeln(myClosure());
document.writeln(myClosure());
</script>
</pre>
</body>
</html>
cs

 

위 코드에서 중요한 부분은 함수를 반환하는 부분이다.
counter 변수는 함수 내에 정의된 변수이므로 함수가 return 되는 시점에 없어져야 하지만
반환하는 익명 함수에서 해당 지역변수를 참조하므로 변수가 유지된다.

 

    스코프 체인으로 이해
        § 글로벌 객체 - closure()함수의 Call객체 - 익명 함수의 Call객체
        § 위와 같은 스코프 체인이 익명 함수가 유효한 동안은 유지된다.
        § 클로저는 별도의 기억공간을 제공하는 구조라고 할 수 있다.

 

closure2test.html

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
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>클로져</title>
</head>
<body>
<pre>
<script type="text/javascript">
function closure(init) {
    var counter = init;
 
    return function() {
        return ++counter;
    }
}
 
var myClosure1 = closure(1);
var myClosure2 = closure(100);
document.writeln(myClosure1());
document.writeln(myClosure2());
document.writeln(myClosure1());
document.writeln(myClosure2());
</script>
</pre>
</body>
</html>
cs

 

myClosure1 myClosure2 각각 별도의 스코프 체인을 가지므로 counter변수 또한 별개로 존재하게 된다.

 

클로저는 간단한 객체로 이해할 수 있다.
클로저 관련 구성요소를 객체로 대응하여 이해할 수도 있다.(클로저는 객체가 아님)
클로저를 감싸는 부모 함수 : 생성자
클로저로 참조되는 지역변수 : 프로퍼티
클로저 자신 : 메서드
위 예제에서 myClosure()호출) : 인스턴스화
클로저를 대입하는 변수(myClosure1) : 인스턴스

클로저와 객체의 사용 용도 차이
• 변수들을 처리하는 기능이 한 가지만 필요한 경우 클로저 사용
• 여러 형태의 처리 기능이 필요한 경우 객체 사용
• 만약 객체지향으로 스크립트 구문을 통일하는 경우 간단한 기능도 객체로 기술한다.

반응형

'교육자료 > Javascript' 카테고리의 다른 글

16-2. 자바스크립트에서 객체의 상속  (0) 2019.05.13
16-1. 자바스크립트의 객체 지향 특성  (0) 2019.05.13
15-4. argument 객체  (0) 2019.05.09
15-3. 변수의 범위  (0) 2019.05.09
15-2. 함수 사용 시 주의  (0) 2019.05.09

+ Recent posts