[JS] 함수 #1. 유효범위(scope), callback, 클로저(closure), 접근 제어
함수선언식 vs 함수표현식
- 함수선언식
```js
functino foo( ) {}
```
- 함수표현식 ( 함수리터럴 )
```js
var foo = function ( ) {};
```
- 일반적으로 함수 표현식을 사용하는 것이 좋다.
- JS를 잘 사용하기 위해서는 함수도 값이라는 것을 이해하는 것이 중요하기 때문.
- 이라고 "자바스크립트 핵심 가이드"에서 얘기하고 있음
- 일반적으로 함수를 선언 할 때, 선언식으로 하냐 표현식으로 하냐 관점에서는 hoisting 정도가 차이점이고,
- JS가 함수표현식을 지원하기 때문에 = 함수는 값 = [클로저, 일회용 함수(즉시eval), 함수를 인자로 전달]이 가능
hoisting 규칙
- ``js let/const`` 변수는 hoisting 되지 않는다.
- ``js var`` 변수는 hoisting되어 선언부만이 유효스코프 최상단으로 이동한다
- ``js var``는 function-scope이기 때문에 함수 최상단으로 호이스팅된다.
- 함수표현식은 ``js var``를 이용하기 때문에 선언부가 호이스팅된다.
- 따라서 일찍 "호출"하는 경우 에러가 발생한다.
- 선언부가 호이스팅 되는거라 변수 접근 자체는 가능하다.
- 함수선언식은 hoisting되어 함수선언 및 바디가 유효스코프 최상단으로 이동한다
- 그래서 어디 정의부보다 위쪽에서 "호출"하는 것이 가능하다
유효범위 ( Scope )
함수 이름 재정의
함수도 변수이기 때문에 ``prompt``같은 함수에 사용되는 이름을 재정의하면 더 이상 함수 ``prompt()``는 사용할 수 없다.
```js
prompt ---X---> function prompt() { prompt code... }
└---------> var prompt = "value"
```
함수를 호출할 때, 생성할 때 입력했던 인수의 개수보다 많거나 적게 입력해도 동작한다.
적게 입력하는 경우 ``undefined``가 되고, 많게 입력하는 경우 무시한다.
arguments 변수
내부 함수
일회용 함수
파라미터로 함수 넘기기 ( callback )
콜백 함수는 어떤 이벤트가 발생하거나, 비동기 작업이 완료되면 이 함수를 실행하라는 의미로 전달하는 함수를 말한다.
함수 리턴
함수 자료형을 지원하기 때문에 함수를 리턴하는 것 또한 가능하다. 이는 클로저에 사용된다.
* 리턴된 함수를 바로 실행할 수도 있다. ``}();``같이 ``();``로 끝나게 되는 경우가 그렇다.
리턴 함수가 아니라 리턴 함수의 실행 결과를 반환받고 싶은 경우 적어주게 된다.
클로저 (closure)
클로저란 내부 함수가 외부 함수1의 변수를 참조하는 상황에서 외부 함수1이 내부 함수를 리턴하는 것을 말한다.
리턴되는 내부 함수가 외부함수1의 변수를 참조할 경우, 이 내부 함수를 클로저 함수라고 부른다.
클로저 함수를 리턴하고 이 클로저 함수에서 외부함수1의 지역변수를 이용하는 경우 외부함수1이 종료되어도 클로저 함수에서 참조하는 지역변수는 사라지지 않는다.
** 클로저는 참조를 가지고 있는 것이지, 값을 가지고 있는 것이 아니다.
그래서 외부함수2에서 외부함수1을 호출하면서 리턴받은 클로저 함수를 변수에 넣어 사용할 수 있다.
즉, 클로저 패턴은 반드시 함수의 실행 결과를 리턴하는 것이 아니라, 함수 자체를 리턴한다.
```js
function foo(name) {
var output = 'hello ' + name;
return {
get_output(){
return output;
}
};
}
var foo1 = foo("closure1");
alert(foo1.get_output());
foo("closure2")();
foo1();
```
JS는 함수 유효범위를 적용하기 때문에 함수의 호출과 종료 시 변수의 생성과 삭제가 일어난다.
위 함수가 만약 다음과 같은 형태라면, 변수 ``output``의 생성과 삭제가 루프 만큼 일어난다.
```js
function foo(name) {
var output = 'hello ' + name;
return output;
}
```
그러나 클로저를 사용했기 때문에 ``foo()``를 호출해 리턴값을 ``foo1``에 할당하고 ``foo()``가 종료되어도 ``js var output``은 사라지지 않아 생성과 삭제가 계속 일어나지 않는다.
접근제어
```js
```
* 내부 함수 ``value``는 외부 함수에 있는 변수의 복사본이 아니라 실제 변수에 접근한다는 것에 유의한다.
* ``js return { };``으로 바로 리턴해도 되고, ``js output = { }; return output;`` 해도 동일하다.
'JS Stack > JS' 카테고리의 다른 글
[JS] memoization, currying (0) | 2017.06.02 |
---|---|
[JS] 함수 #2. Call pattern, 생성자 대안(함수형 패턴), 상속 (0) | 2017.05.31 |
[JS] 객체, 프로토타입, 기본 타입에 기능 추가 (0) | 2017.05.29 |
[Regex] JS (0) | 2017.05.28 |
[JS] TIP (0) | 2017.05.25 |