JavaScript

[JavaScript] 함수

함수 개요

익명 함수

var myFunc = function() {
    var output = prompt('숫자 입력', '숫자');
    alert(output);
};
myFunc();

위 코드 첫 문장의 우변을 익명함수라고 합니다. 우변만 보았을 때, 이 함수는 이름이 없으므로 익명함수라고 부릅니다. 익명함수는 위의 코드처럼 변수에 넣어 사용합니다. 

선언적 함수

function myFunc() {
    var output = prompt('숫자 입력', '숫자');
    alert(output);
}
myFunc();

위와 같이 function 키워드를 이용하여 함수를 선언하는 경우를 선언적 함수라고 합니다. 얼핏 보면 익명 함수와 선언적 함수가 큰 차이가 없어보입니다. 하지만 생성하는 시점에 따라 조금의 차이가 있습니다. 예를 들어 아래의 코드의 첫 문장은 실행되지 않습니다.

myFunc();
var myFunc = function() { alert('myFunc() call!!!'); };

선언적 함수의 경우에는 script 태그를 실행하기 전에 가장 먼저 읽혀지지만, 익명 함수의 경우는 한 줄, 한 줄 실행되면서 익명 함수가 정의된 부분을 만날 때 정의되는 것이므로 위의 myFunc();를 호출하기 전에 익명 함수를 정의 했어야 합니다.(또는 두 번째 줄을 선언적 함수의 형태로 정의해야 합니다.)

 

매개 변수와 리턴값

function myFunc(x) { return x*x; }
alert(myFunc(3));

모든 프로그래밍 언어와 크게 다른 부분이 없으므로 설명할 부분이 없다. 

 

매개 변수

보통 일반적인 프로그래밍 언어들은 매개 변수의 개수가 맞지 않으면 오류가 납니다. 하지만 자바스크립트는 초과된 매개 변수는 그냥 무시한 채 진행됩니다. 또 원래 지정된 매개 변수보다 적게 입력했을 경우에는 undefined가 입력됩니다. 그리고 함수에 따라서는 매개 변수의 개수에 따라서 다른 기능을 하도록 구현되어 있기도 하는데, 예를 들어 Array() 함수는 인자가 없을 때, 하나일때, 두 개 이상일 때 그 기능이 모두 다릅니다.(가변인자 함수)

var array1 = Array();           // 빈 배열 생성
var array2 = Array(10);         // 10 크기의 배열 생성
var array3 = Array(1,2,3,4,5);  // 1,2,3,4,5로 5 크기의 배열을 만듬

 

가변인자 함수

자바스크립트의 모든 함수는 변수 arguments라는 인자를 자동으로 갖습니다. arguments는 매개 변수의 배열입니다. 이것을 이용하면 위의 Array() 함수처럼 인자 개수에 따라서 다른 기능을 하도록 구현할 수도 있습니다.

function sumAll() {
    var sum=0;
    for(var i in arguments) {
        sum += arguments[i];
    }
    return sum;
}

alert(sumAll(1,2,3,4,5,6,7,8,9));
function myFunc() {
    var length = arguments.length; // 매개변수의 개수를 가져옵니다.
    
    if(length == 0) {
        // 매개 변수가 없을 때
    }
    else if(length == 1) {
        // 매개 변수가 1개일 때
    }
    else {
        // 매개 변수가 2개 혹은 그 이상일 때
    }
}
arguments.length : 매개변수의 개수를 반환합니다.

 

내부 함수

내부 함수는 함수 내부에 선언한 함수입니다. 내부 함수를 선언하면 함수의 외부에서 내부 함수를 호출할 수 없으며 함수 내부에서만 동작합니다. 또한, 함수 내부에서 내부 함수를 호출할 때, 내부 함수가 함수의 외부에 내부 함수와 같은 이름이 있을 때, 내부 함수가 우선적으로 호출됩니다.

function pythagoras(width, height) {
    function square(x) {
        return x*x;
    }
    return Math.sqrt(square(width) + square(height));
    // square(x)는 함수의 내부에서만 호출할 수 있습니다.
}
// 함수의 외부에서 square(x)를 호출할 수 없습니다.

 

함수를 매개 변수로 받는 함수

자바스크립트에서는 함수도 하나의 변수이므로 매개 변수로 함수를 전달하는 것이 가능합니다.

// 인자로 받은 함수를 10번 호출합니다.
function callFunctionTenTimes(otherFunction) {
    for(var i=0; i<10; i++) {
        otherFunction();
    }
}

// 익명 함수의 형태
callFunctionTenTimes(function() {
    alert('Hello World!');
});

// 선언적 함수의 형태
function helloFunction() {
    alert('Hello World2!');
}
callFunctionTenTimes(helloFunction);

위와 같이 익명 함수의 형태로도, 선언적 함수의 형태로도, 또는 익명 함수를 변수에 저장한 함수 변수로도 인자를 전달할 수 있습니다.

 

함수를 리턴하는 함수와 클로저

// 익명 함수를 리턴하는 함수
function outerFunction(name) {
    var output = 'Hello' + name + '!';
    return function () {
        alert(output);
    };
}

outerFunction('Mickey')();
/*  다소 이상한 표현처럼 보일 수 있지만
    outerFunction('Mickey')라고 입력하면 익명 함수 그 자체를 리턴한다.
    즉 리턴된 익명 함수를 실행하기 위해서는 ()를 하나 더 붙여 주어야
    Hello World!가 출력된다. */

위의 코드와 같이 함수 자체를 리턴해서 활용할 수도 있습니다. 그런데 여기서 주의깊게 봐야할 부분은 output입니다. 보통 함수 내부에서 선언한 지역변수는 함수 외부에서 사용할 수 없습니다. 하지만 위와 같이 코드를 작성하면 output이라는 지역변수를 외부에서 호출할 수 있게 된 것처럼 보입니다. 이러한 현상을 클로저라고 합니다.

이렇게 지역 변수를 남겨두는 현상을 클로저라고 부르기도 하고 outerFunction()으로 인해 생성된 공간을 클로저라고 부르기도 합니다. 또한, 리턴되는 함수 자체를 클로저라고 부르기도 하며, 지역 변수 output을 클로저라고 부르기도 합니다.

 

자바스크립트 내장 함수

자바스크립트가 자체적으로 갖고 있는 함수를 내장 함수라고 합니다. 지금까지 사용했던 alert() 함수나 prompt(), confirm() 등이 내장 함수의 예입니다. 

인코딩과 디코딩

 - 인코딩 : 문자를 컴퓨터에 저장하거나 통신에 사용할 목적으로 부호화하는 방법
 - 디코딩 : 부호화된 문자를 원래대로 되돌리는 방법

  • escape() : 적절한 정도로 인코딩. 영문 알파벳, 숫자, @,*,-,_,+,.,/를 제외한 모든 문자를 인코딩합니다.
    1바이트 문자는 %XX의 형태로, 2바이트 문자는 %uXXXX의 형태로 변환합니다.
  • encodeURI() : 최소한의 문자만 인코딩. escape()에서 :,;,/,=,?,&(인터넷 주소에 사용되는 문자)는 변환하지 않습니다.
  • encodeURIComponent() : 대부분의 문자를 인코딩. 알파벳과 숫자를 제외한 모든 문자를 인코딩합니다.
    UTR-8 인코딩과 같습니다.
     
  • unescape()
  • decodeURI()
  • decodeURIComponent()
var URI = 'https://www.google.com/search?q=한글입니다.';

var output='';

output += '*escape()\n';
output += escape(URI) + '\n\n';

output += '*encodeURI()\n';
output += encodeURI(URI) + '\n\n';

output += '*encodeURIComponent()\n';
output += encodeURIComponent(URI) + '\n\n';

alert(output);
/* 출력 결과
*escape()
https%3A//www.google.com/search%3Fq%3D%uD55C%uAE00%uC785%uB2C8%uB2E4.

*encodeURI()
https://www.google.com/search?q=%ED%95%9C%EA%B8%80%EC%9E%85%EB%8B%88%EB%8B%A4.

*encodeURIComponent()
https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3D%ED%95%9C%EA%B8%80%EC%9E%85%EB%8B%88%EB%8B%A4.
*/

 

그 외 기본 내장 함수

  • eval(string) : string을 자바스크립트 코드로 실행합니다. eval()을 통해 정의한 변수도 사용할 수 있습니다.
  • isFinite(number) : number가 유한 값이면 true를 리턴합니다. 0으로 숫자를 나눠 Infinity 또는 -Infinity라는 값을 만들 수 있고, 이 둘은 isFinite()에서 false를 리턴합니다. 숫자가 아닐 때에도 false를 리턴합니다.
  • isNaN(number) : number가 NaN인지 확인합니다.
  • parseInt(string) : string을 정수로 바꿉니다.
  • parseFloat(string) : string을 유리수로 바꿉니다.
NaN은 스스로를 비교할 수 없는 형태이므로 반드시 함수 isNaN()을 이용하여 비교하여야 합니다.
예를 들어 if(NaN == NaN)은 false를 반환합니다. 비교할 수 없기 때문입니다.
parseInt()와 Number()
두 함수의 기능은 비슷하지만 조금 다릅니다. Number() 함수는 문자열에 숫자 이외의 문자가 있으면 NaN을 반환하지만 parseInt()와 parseFloat()는 앞자리부터 바꿀 수 있는 부분까지만 변환하여 반환합니다.
var won = '1000원';
var dollar = '1.5$';

alert(Number(won) + ' : ' + Number(dollar));         // NaN : NaN
alert(parseInt(won) + ' : ' + parseInt(dollar));     // 1000 : 1
alert(parseFloat(won) + ' : ' + parseFloat(dollar)); // 1000 : 1.5
단, parseInt()와 parseFloat()는 앞자리부터 바꾸기 때문에 '$1000'와 같은 문자는 숫자로 바꿀 수 없습니다.
parseInt()와 parseFloat()의 인자
아래와 같이 0으로 시작하거나 0x로 시작하면 각각 8진수, 16진수로 인식한 후 10진수로 변환합니다.
alert(parseInt('0x273'));   // 627
alert(parseInt('0273'));    // 187

혹은 두 번째 매개 변수에 진법을 명시할 수도 있습니다.

alert(parseInt('FF', 16));  // 255
alert(parseInt('11', 8));   // 9

추가로 parseFloat에서 e를 입력하면 10의 거듭제곱으로 인식합니다.

alert(parseFloat('52.273e5'));  // 5227300

댓글

댓글 본문
작성자
비밀번호
  1. 지나가다
    깔끔한 정리 감사합니다.
    인수와 매개변수 용어를 구분해서 사용했으면 어떨까합니다.
    arguments는 매개 변수의 배열입니다 -> 이부분을
    arguments는 인수들의 집합입니다. 구조가 인덱스, 값의 형식이기 배열처럼 사용할 수 있습니다.
  2. 방울토마토
    깔끔한 정리 자료 감사합니다 :D
  3. 해바라기
    정리가 참 잘 되어있네요. 잘 보고 갑니다
버전 관리
miki
현재 버전
선택 버전
graphittie 자세히 보기