내부함수
내부함수는 프로그램의 규모가 커질수록 다른사람과 함께 프로그램을 개발하게 되는데 이때 발생하는 여러가지 충돌을 막기위한 방법중 하나이다.
다음과 같은 형태로 구현한다.
function 외부함수 () {
function 내부함수1() {
//함수 코드
}
function 내부함수2() {
//함수 코드
}
//함수 코드
}
피타고라스를 정리하는 함수 pythagoras()를 만들어 내부함수를 구현해본다.
function pythagoras(width,height) {
return Math.sqrt(width*width + height*height);
}
숫자를 제곱하는 부분은 피타고라스에서 자주 사용되는 내용이므로 별도의 square()함수로 구현한다.
function square(x) {
return x*x;
}
function pythagoras(width,height){
return Math.sqrt(square(width) + square(height));
}
만약 규모가 큰 웹 애플리케이션을 만들 때 같은 팀 구성원이 square의 다른 뜻인 "직각"으로 착각하여 같은 이름으로 직각 삼각형인지 확인하는 함수를 만들었다면 문제가 발생하게된다.
/*남궁 사원이 만든 square함수*/
function square(x) { //제곱근을 구하는 함수
return x*x;
}
function pythagoras(width,height){
return Math.sqrt(square(width) + square(height));
}
alert(pythagoras(3,4));
/*유 사원이 만든 square함수*/
function square(width, height, hypotenuse) {//삼각형이 직각인지 확인하는 함수
if (width * width + height * height == hypotenus * hypotenuse) {
return true;
}else {
return false;
}
}
남궁 사원의 square() 함수는 유 사원의 square()함수에 덮어 씌어진다.
따라서 pythagoras()함수 내부에서는 유 사원의 square() 함수를 사용하게 된다.
해결방안은 두 사원이 사전에 협의하여 함수이름을 서로 다른 이름으로 사용하거나, 가변 인자 함수로 같은 이름이어도 서로 다른 기능을 수행하게 하여 충돌을 예방할 수 있다.
그렇지 않다면 원하지 않는 결과가 발생하게된다.
이와 같은 상황에서 내부함수를 사용하면 간단하게 함수 이름 충돌을 막을 수 있다.
function pythagoras(width,height){
function square(x) { //제곱근을 구하는 함수
return x*x;
}
return Math.sqrt(square(width) + square(height));
}
위와 같이 내부 함수로 구현하면 되지만 한가지 주의할 점이 있다.
내부 함수는 내부 함수가 포함되는 함수에서만 사용이 가능하다.
pythagoras() 함수 외부에서 square()함수를 사용할 수 없다. 이것은 지역변수 개념과도 같다.
자기호출 함수
자기호출 함수는 다음과 같은 형태이며 함수를 생성하자마자 호출한다.
// 타입1
(function () {
//코드
//코드
//코드
})();
// 타입2
(function () {
//코드
//코드
//코드
}());
// 타입3
!function () {
//코드
//코드
//코드
}();
보통은 다른 개발자에게 영향을 주지 않게끔 사용한다. (익명함수로 구성되어있다.)
function(){}을 ()괄호로 한번 묶어주고 그 옆에 바로 ()를 한번 더 선언하면 함수가 선언되자마자 따로 호출문 없이 실행된다.
이전 포스팅에서 설명했듯이 함수는 호출시 함수명 바로 옆에 (); 괄호를 열고닫음으로써 함수를 호출하여 함수내부의 코드를 실행한다.
따라서 function(){} 선언 자체를 (괄호)로 묶는 순간 자료형과 같은 상태로 볼 수 있으며 함수명(); 에서 함수명이라고 볼 수 있다.
따라서 function(){} 선언 자체를 (괄호)로 묶는 문법은 익명함수에서 호출할 함수 명을 대체하는것으로 볼 수 있다.
(즉, 함수명(); 에서 '함수명' 에 해당한다고 볼 수 있다. )
또한 아래 코드와 같이 매개변수를 넘길수도 있다.
(function (msg) {
console.log(msg);
}("hello!"));
(function (msg) {
console.log(msg);
})("hello!");
!function (msg) {
console.log(msg);
}("hello!");
함수 선언부의 ()에 argument로 사용될 변수명을 입력해 준 뒤, 마지막 괄호에서 호출할때 넘길 매개값을 작성하면 함수 블록 내부에서 해당 값을 매개변수로 사용할 수 있게 된다.
API를 보다가 많이 마주칠 수 있으므로 자기호출함수의 형태를 꼭 기억하자!
콜백함수
자바스크립트 에서는 함수도 하나의 자료형이므로 매개변수로 전달할 수 있다.
이렇게 매개변수로 전달하는 함수를 콜백함수 라고 부른다.
다른 프로그래밍 언어에서는 찾아보기 힘든 개념이다.
function callTenTimes(callback) {
for (var i = 0; i < 10; i++) {
callback();
}
}
/*
function callback () {
alert('함수 호출');
}
*/
var callback = function() {
alert('함수 호출');
}
callTenTimes(callback);
callback함수를 매개변수로 받아 10번 호출하는 함수 로직이다.
코드를 실행하면 '함수 호출' 이라는 문자열을 담은 alert창을 10회 출력한다.
익명 콜백함수
function callTenTimes(callback) {
for (var i = 0; i < 10; i++) {
callback();
}
}
callTenTimes(function() {
alert('함수 호출');
});
콜백함수는 익명함수로 바로 선언하여 사용하는 경우가 많다.
위 코드와 같이 callTenTimes () 함수의 매개변수로 익명함수를 곧바로 입력할 수도 있다.
함수를 매개변수로 전달하는 것은 분명한 이유가 있다.
이전 포스팅에서 예를들었던것과 같이 매개변수로 전달받은 콜백 함수를 반복문을 통해 여러번 실행할 수 있고, 이러한 형태는 이벤트에서 주로 쓰이게된다.
'JavaScript > VanillaJS' 카테고리의 다른 글
짧은 조건문 (논리합 || or 논리곱 &&) (0) | 2022.01.22 |
---|---|
자바스크립트 (0) | 2022.01.22 |
함수를 리턴하는 함수 , 클로저 (0) | 2022.01.18 |
함수의 매개변수와 리턴값 , 가변인자 함수 (0) | 2022.01.17 |
함수 function 정의와 호출순서 (익명 함수 / 선언적 함수) (0) | 2022.01.17 |