저번주는 한주 쉬어가는 시간을 가지면서 원기보충을 한거같지만 사실 더 피곤하다.
드디어 배열이 끝나서 이제 함수로 넘어가도록 해보자 산넘고 물을 건넜더니 또 산이있다.
함수와 프로토타입 체이닝
자바스크립트에서 가장 중요한 개념 1순위 그건 함수이다.
함수를 얼마나 이해하고 활용하느냐에 따라서 고급 자바스크립트 개발자가 되느냐 마느냐를 결정할 정도이니깐 그만큼 중요하니깐 정신차리고 시작하자.
이번 장에서는 특정기능을 제공하는 코드를 정의하고, 모듈화처리, 클로저, 객체생성 등 자바스크립트의 근간이 되는 많은 기능을 알아본다.
1)함수 정의
자바스크립트에서 함수를 생성하는 3가지 방법을 제공한다.
- 함수 선언문
- 함수표현식
- Function() 생성자 함수
1-1)함수 리터럴
함수도 일반 객체처럼 값으로 취급된다. 객체리터럴 방식으로 일반 객체를 생성할 수 있는 것처럼, 함수 리터럴을 이용해서 삼수를 생성할 수 있다. 함수 선언문 이나 함수 표현식 방법 모두 함수 리터럴방식으로 함수를 생성한다.
1 2 3 4 | // (1) (2) (3) function add(x, y) { return x + y; //(4) } | cs |
(1) function 키워드 : 자바스크립트 함수 리터럴은 function 키워드로 시작
(2) 함수명 : 함수명은 함수 몸체의 내부 코드에서 자신을 재귀적으로 호출하거나 자바스크립트 디버거가 해당 함수를 구분하는 식별자로 사용, 함수명은 선택적이고 함수명이 없는 함수를 익명 함수라고한다.
(3) 매개변수 리스트 : 매개변수는 C 언어와 같은 기존 언어의 함수 매개변수 형태와 거의 비슷하지만 매개변수 타입을 기술 하지 않는다는 차이가 있다.
(4) 함수 몸체 : 실제 함수가 호출됐을 때 실행되는 코드 부분
1-2)함수 선언문 방식으로 함수 생성하기
함수 선언문 방식은 함수 리터럴 형태와 같다. 여기서 주의점은 함수 선언문 방식은 반드시 함수명이 정의 되어 있어야 한다는 것이다.
1 2 3 4 5 6 | //add( ) 함수 선언문 function add(x, y) { return x + y; } console.log(add(3, 4)); // 7 | cs |
함수 선언문 형태로 add() 함수를 구현했다. 함수명 add가 있고 또한 이 함수명으로 함수를 호출하고 있다.
1-3)함수 표현식 방식으로 함수 생성하기
함수도 하나의 값처럼 취급된다. 따라서 숫자, 문자열 처럼 변수에 할당할 수 있다.
이런 방식으로 함수 리터럴로 함수를 만들고, 생성된 함수를 변수에 할당하여 함수를 생성하는 것을 함수 표현식이라고 한다.
1 2 3 4 5 6 7 8 9 | //add() 함수 표현식 (1) var add = function (x, y) { return x + y; }; var plus = add; // (2) console.log(add(3, 4)); // 7 (3) console.log(plus(5, 6)) // 11 (4) | cs |
여기서 함수 리터럴로 생성한 함수는 함수명이 없으므로 익명 함수이다.
함수 표현식은 함수 선언문 문법과 거의 유사하고 차이점은 함수 표현식 방법에서는 함수명이 선택사항이며 보통 사용하지 않는다.
(1) add 변수는 함수 리터럴로 생성한 함수를 참조하는 변수이다. 1-2예제 처럼 함수 이름이 아니라는 것에 주의 하자. add와 같이 함수가 할당된 변수를 함수 변수라고 부른다.(이 책에서는 그런단다...)
(2) 함수 변수 add는 함수의 참조값을 가지므로 또 다른 변수 plus에도 그 값을 그대로 할당할 수 있다. 그렇기 때문에 (4)에서 두값을 더하는 코드가 수행된 것이다.
(3) 함수 표현식으로 생성된 함수를 호출하려면 함수 변수를 사용해야 한다. (1)에서 생성한 함수의 함수 변수는 add이므로 add(3, 4) 이렇게 함수를 호출하는 것이 가능하다.
(4) plus 또한 add 함수 변수와 같은 함수를 참조하는 함수 변수이므로 plus(5, 6)과 같은 형태로 함수를 호출하는 것이 가능하다.
이름이 없는 함수형태를 익명함수라고 하고 익명함수를 만들고 이를 변수에 할당한걸 익명 함수를 이용한 함수 표현식 방법(익명 함수 표현식)이라고 한다.
함수 이름이 포함된 함수 표현식은 기명 함수 표현식 이라고 한다.
기명 함수 표현식에는 주의점이 있다.
1 2 3 4 5 6 7 8 | var add = function sum(x, y) { return x + y ; }; // (1) console.log(add(3, 4)); // 7 (2) console.log(sum(3, 4)); // Uncaught ReferenceError : sum is not defined 에러 발생 (3) | cs |
(1) sum() 함수를 정의하고, 이 함수를 add 함수 변수에 할당한다. 예제에서 특이한 점은 add() 함수 호출 (2)는 결과값이 성곡적으로 리턴된 반면 sum() 함수 호출의 (3)경우 에러가 발생한다는 것이다.
이것은 함수 표현식에서 사용된 함수이름이 외부 코드에서 접근이 불가능 하기 때문이다.
실제로 함수 표현식에 사용된 함수이름은 정의된 함수 내부에서 해당 함수를 재귀적으로 호출하거나, 디버거 등에서 함수를 구분할 때 사용된다.
그렇기 때문에 함수 이름으로 사용된 sum으로 함수 외부에서 해당 함수를 호출할 때 sum() 함수가 정의 되어 있지 않다는 에러가 발생한다.
앞 내용에서 add() 함수는 어떻게 함수 이름으로 함수 외부에서 호출이 가능했을까? 함수 선언문 형식으로 정의된 add() 함수는 자바스크립트 엔진에 의해 다음과 같은 함수 표현식 형태로 변경된다.
1 2 3 | var add = function add(x, y) { return x + y; }; | cs |
함수 이름과 함수 변수의 이름이 add로 같아서 함수 이름으로 함수가 호출되는 것처럼 보이지만, 실제로 add함수 변수로 함수 외부에서 호출이 가능하게 된 것이다.
함수 표현식에서는 함수이름이 선택적이지만, 함수 이름을 이용하면 함수 코드 내부에서 함수 이름으로 함수의 재귀적인 호출 처리가 가능하다.
1 2 3 4 5 6 7 8 9 10 | var factorialVar = function factorial(n) { if (n <= 1) { return 1; } return n * factorial(n-1); // (1) }; console.log (factorialVar(3)); // 6 (2) console.log (factorial(3)); // undefined (3) | cs |
(2) 함수 외부에서는 함수 변수 factorialVar로 함수를 호출했으며, 함수 내부에서 이뤄지는 재귀 호출은 factorial() 함수 이름으로 처리한다는 것을 알 수 있다.(1)
(3) 앞서 설명한 것과 마찬가지로 함수명 factorial()으로 함수 외부에서 해당 함수를 호출하지 못해 에러가 발생한다..
1-4)Function() 생성자 함수를 통한 함수 생성하기
자바스크립트의 함수도 Function ( )이라는 기본 내장 생성자 함수로부터 생성된 객체라고 볼 수 있다.
1 2 3 4 | new Function (arg1, arg2, ... argN functionBody) arg1 arg2, ... , argN - 함수의 매개변수 functionBody - 함수가 호출될 때 실행될 코드를 포함한 문자열 | cs |
1 2 3 | var add = new Function ('x', 'y', 'return x + y'); console.log(add(3,4)); /// 7 | cs |
일반적으로 Function () 생성자 함수를 사용한 함수 생성 방법은 자주 사용되지 않으므로 더 이상 다루지 않는다.