상세 컨텐츠

본문 제목

[javascript] 함수

Web/Javascript

by 클리엘 클리엘 2020. 3. 27. 15:22

본문

1. 개요

 

일련의 처리과정을 하나의 코드로 묶어 사용하는 것을 함수라고 하며 기본적으로 다음과 같은 형태로 작성됩니다.

function 함수명() {
	처리내용
}

2. 익명 함수

 

위에서 처럼 함수를 정의할 때는 함수명이 있는 것이 기본이지만 다음과 같이 함수명이 없는 형태로 선언하는 경우를 익명 함수라고 합니다.

var myfunc = function() {
	var i = 10;
	var j = 20;

	alert(i + j);
};

myfunc 변수를 사용해 함수 자체를 대입함으로써 함수 데이터형의 변수를 사용하게 됩니다. 혹은 다음과 같은 방법으로 익명 함수를 대체할 수도 있습니다.

var myfunc = () => {
	var i = 10;
	var j = 20;

	alert(i + j);
};

function을 생략하고 함수의 본문 사이에 '=>'기호를 사용했는데 이 때문에 이를 '화살표 함수'라고도 합니다. 화살표 함수는 일반 함수와 마찬가지로 매개변수를 지정할 수 있으며 return을 따로 사용하지 않아도 결과를 반환하는 특징이 있습니다.

var myfunc = (i, j) => i + j;

alert(myfunc(10, 20));

익명 함수나 화살표 함수를 호출할 때는 함수를 가진 변수명을 통해 호출합니다.

myfunc();

단, 익명 함수와 화살표 함수에서 this키워드를 사용할때는 주의해야 합니다. 화살표함수에서 this는 전역 객체(웹브라우저라면 window)이지만 익명 함수에서 this키워드는 자신이 바인딩하고 있는 객체라는 차이점이 있습니다.

 

3. 선언적 함수

 

함수명을 지정해 함수를 정의하면 이를 선언적 함수라고 할 수 있습니다.

function myfunc() {
	var i = 10;
	var j = 20;

	alert(i + j);
};

위 예제에서 myfunc가 함수명에 해당합니다.

 

4. 함수 실행 순서

 

그렇게 하는 경우는 없지만 같은 이름의 함수를 여러 번 정의할 수 있습니다.

function myfunc() {
	var i = 10;
	var j = 20;

	alert(i + j);
};

function myfunc() {
	var i = 1;
	var j = 2;

	alert(i + j);
};

myfunc();

이 예제에서는 결과로 3을 표시하는데 같은 이름의 함수가 재정의되면 뒤에 있는 함수의 내용으로 바뀌게 됩니다. 하지만 같은 함수라 하더라도 선언적 함수가 우선적으로 정의되고 그 뒤에 익명 함수가 정의되므로

var myfunc = function() {
	var i = 10;
	var j = 20;

	alert(i + j);
};

function myfunc() {
	var i = 1;
	var j = 2;

	alert(i + j);
};

myfunc();

위 예제는 결과로 30을 표시하게 됩니다. 함수의 실행 순서에 따라 결과가 달라질 수 있으므로 주의가 필요합니다.

 

5. 매개변수

var myfunc = function(i, j) {
	alert(i + j);
};

myfunc(10, 30);

위 예제에서 myfunc는 함수에서 i와 j값을 받도록 되어있고, 실제 함수를 호출할 때도 i는 10, j는 30의 값을 전달하고 있습니다. 이렇게 함수를 통해 값을 지정하고 전달받는 변수를 함수의 매개변수라고 합니다.

 

매개변수를 가진 함수를 호출할 때는 통상 매개변수의 수만큼 값을 지정하지만 그렇게 하지 않아도 오류로 인식하지는 않습니다.

var myfunc = function(i, j) {
	alert(i + j);
};

myfunc(10, 30, 20);

예제에서 myfunc 함수는 2개의 값을 받도록 되어 있지만 함수를 호출할때는 3개의 값을 지정하고 있습니다. 하지만 오류없이 함수는 동작합니다.

 

반대로 매개변수의 값을 더 적게 지정하게 되면 값이 들어가야 할 매개변수는 자동으로 undefined 처리됩니다. 이런 경우 함수 내부에서는 특정 변수가 undefined면 다른 값이 대신 들어갈 수 있도록 다음과 같이 작성할 수 있습니다.

var myfunc = function(i, j) {
	j = j || 30;

	alert(i + j);
};

myfunc(10);

따라서 위 예제에서는 j에 값을 전달하지 않으면 30 값이 대신 들어가게 됩니다. 참고로 예제보다 더 간단하게 기본값을 지정하려면 다음과 같이 할 수도 있습니다.

var myfunc = function(i, j = 30) {
	alert(i + j);
};

myfunc(10);

다만 위 예제는 최신의 브라우저가 아니면 작동하지 않을 수 있습니다.

 

어쨌건 실제 매개변수와 호출할 때의 매개 변숫값이 일치하지 않으면 이를 오류로 처리하지 않는다는 것이 중요합니다. 이를 이용해 함수로 전달하는 매개 변숫값을 유동적으로 처리할 수 있는 방법이 존재하는데 바로 arguments라는 매개변수 배열을 이용하는 것입니다.

var myfunc = function(i, j) {
	alert(arguments.length);
	alert(arguments[2]);
};

myfunc(10, 30, 20);

arguments는 자바스크립트에서 기본적으로 제공하는 객체로서 함수로 전달되는 매개변수값을 배열로서 저장하고 있습니다. 때문에 각각의 값은 배열 단위로 '[인덱스]'형태로 가져올 수 있으며 배열 자체의 길이는 length속성을 통해 가져올 수 있습니다. 따라서 위 예제의 결과로는 각각 3과 20을 출력하게 됩니다.

 

만약 arguments만을 단독으로 사용하기로 결정했다면 함수의 매개변수는 생략할 수 있습니다.

var myfunc = function() {
	alert(arguments.length);
	alert(arguments[2]);

	alert(arguments[0] + arguments[1]);
};

myfunc(10, 30, 20);

또한 arguments라는 객체를 사용하지 않고 직접 매개변수를 정의하려면 다음과같이 ...을 사용한 전개 연산자를 통해 함수의 매개변수를 작성할 수 있습니다.

var myfunc = function(...param) {
	alert(param.length);
	alert(param[2]);

	alert(param[0] + param[1]);
};

myfunc(10, 30, 20);

이때 arguments는 배열이 아닌 객체로서 취급될 수 있지만 전개 연산자로 지정된 변수는 단순 배열에 해당한다는 차이점이 있습니다.

 

물론 함수를 호출할 때도 전개 연산자를 사용할 수 있습니다.

var myfunc = function(...param) {
	alert(param.length);
	alert(param[2]);

	alert(param[0] + param[1]);
};

var myArr = [10, 30, 20];
myfunc(...myArr);

전개 연산자와 일반 매개변수가 같이 존재하는 경우도 가능하며 이럴 때는 해당하는 순서만 잘 맞춰주면 됩니다.

var myfunc = function(i, j, ...param) {
	alert(param.length);
	alert(param[2]);

	alert(param[0] + param[1]);
};

var myArr = [10, 30, 20];
myfunc(10, 20, ...myArr);

함수에서 전개 연산자만 존재하는 경우에도 일반 변수와 전개 연산자를 결합하여 전달할 수 있습니다.

var myfunc = function(...param) {
	alert(param.length);
	alert(param[2]);

	alert(param[0] + param[1]);
};

var myArr = [30, 20];
myfunc(10, ...myArr);

참고로 전개연산자를 통해 함수를 호출하기 이전에는 apply메서드를 사용했습니다.

var myfunc = function(...param) {
	alert(param.length);
	alert(param[2]);

	alert(param[0] + param[1]);
};

var myArr = [10, 30, 20];
myfunc.apply(null, myArr);

apply메서드는 모든 함수에 기본적으로 제공되는 함수로서 첫 번째 매개변수로 함수에서 사용할 this객체, 두 번째는 매개변수로 배열 자체를 지정해 함수에 전달하도록 합니다.

 

참고로 배열에서 전개연산자를 사용하면 편리하게 배열을 복사(깊은복사)할 수 있습니다.

var myArray = [1, 2, 3, 4, 5];
var myArray2 = [...myArray];

마지막으로 위에서 처럼 배열이나 전개연산자 대신 함수로 값을 전달하고자 할때 객체를 사용하는 경우도 있습니다.

var myfunc = function(myObject) {
	var n1 = myObject.v1;
	var n2 = myObject.v2;

	alert(n1 + n2);
};

myfunc({v1 : 10, v2 : 20});

객체는 추후에 알아보겠습니다.

 

6. 리턴 값

 

함수는 위 예제에서와 같이 alert나 기타 다른 방법을 통해 함수를 수행하는 것으로 끝낼 수 있지만 특정값을 반환받아 함수를 호출하는 지점부터 처리를 계속 수행할 수도 있습니다.

var myfunc = function(i, j) {
	return i + j;
};

var rv = myfunc(10, 30);
alert('결과는 ' + rv);

함수에서 결괏값을 리턴(반환)하려면 return문을 써야 합니다. 그러면 함수 호출의 결과로써 해당 값을 반환하게 되며 함수를 호출하는 지점에서 값을 받을 수 있게 됩니다. (return 다음에 반환 값을 지정하지 단순히 함수를 종료하는 역활을 수행합니다.)

 

함수는 특정값을 반환할 수 있지만 경우에 따라서 함수 자체를 반환하는 것도 가능합니다.

var myfunc = function(i, j) {
	var r = i + j;

	return function() {
		alert('실행결과 : ' + r);
	};
};

myfunc(10, 30)();

이때 myfunc안에서 사용된 지역변수 r에 주목해 주세요. 원래는 myfunc함수가 종료되면 지역변수도 소멸해야 하지만 반환되는 함수로 인해 변수가 살아있게 되며 이런 현상을 '클로저'라고 합니다.

 

7. 내부 함수

 

함수 안에 또 다른 함수를 정의하는 것을 말합니다.

var myfunc = function(i, j) {
	return myfunc2(i, j);

	function myfunc2 (i, j) {
		return i + j;
	};
};

var rv = myfunc(10, 30);
alert('결과는 ' + rv);

myfunc라는 함수 안에서 myfunc2라는 새로운 함수를 정의해 2개의 매개변수값을 더하도록 하였습니다. 함수안에서도 또 다른 함수를 가지는 것이 가능한 것입니다. 이러한 내부 함수는 내부함수를 포함하는 함수만 사용할 수 있으며 다른 외부함수에서는 다른 함수안에 정의된 내부함수를 호출할 수 없습니다. 따라서 내부함수는 정의하고자 하는 함수안에서만 필요한 기능을 정의할 때 유용하게 사용할 수 있습니다.

 

8. 콜백 함수

 

함수를 호출할 때 매개변수에 특정 함수를 지정하고 함수의 결과로 해당 함수를 호출하게 되는 것을 '콜백함수'라고 합니다.

var myfunc = function(i, j, fnc) {
	fnc(i + j);
};

var message = function (r) {
	alert('실행결과 ' + r);
};

myfunc(10, 30, message);

예제에서는 myfunc 함수를 호출할때 message라는 함수를 매개변수에 전달하고 있고, myfunc에서는 전달된 값을 더하여 매개변수를 통해 전달된 함수를 호출하고 있습니다.

 

콜백 함수는 예제처럼 함수를 미리 정의해 놓고 사용할 수 있지만 다음과 같이 익명 함수로서 처리할 수도 있습니다.

var myfunc = function(i, j, fnc) {
	fnc(i + j);
};

myfunc(10, 30, function (r) { alert('실행결과 ' + r); });

9. 기본 내장 함수

 

필요에 따라 수많은 함수를 만들어 사용하기도 하지만 자바스크립트 내부에 기본적으로 정의된 함수를 이용하는 경우도 많습니다. 가장 많이 사용되는 alert이나 confirm 같은 함수도 기본적으로 제공하는 함수중 하나에 해당합니다.

 

(1) setTimeout / setInterval

 

지정된 시간 후 지정된 함수를 호출하는 함수입니다.

var myfunc = function(i, j) {
	alert('실행결과 : ' + (i + j));
};

setTimeout('myfunc(10, 20)', 3000);

setTimeout 함수의 첫 번째 인수로는 호출할 함수를 지정합니다. 예제에서는 함수 호출시 함수의 매개 변숫값을 지정해야 하기에 문자열 형태로 함수를 지정했지만 매개변수가 필요 없는 경우 setTimeout(myfunc, 3000); 형태로 호출할 함수를 지정할 수 있습니다.

 

setTimeout 함수의 두 번째 인수로는 함수를 실행할 시간 값입니다. 밀리초 단위로 1000이면 1초에 해당합니다. 따라서 3000이면 3초 후에 함수를 호출하게 됩니다.

 

setInverval 함수의 인수는 setTimeout과 동일하지만 차이점은 setTimeout은 한 번만 함수를 호출하지만 setInverval함수는 지정된 시간마다 매번 함수를 호출한다는 차이점이 있습니다. 그러므로

setInterval('myfunc(10, 20)', 3000);

위와 같이 했다면 매 3초마다 myfunc함수를 호출하게 됩니다. 또한 타이머 함수는 자바스크립트가 아니라 웹브라우저가 실행하고 그 결과를 자바스크립트에 알려주는 방식이므로 통상 자바스크립트가 수행하는 다른 함수들을 모두 실행한 뒤에 타이머 함수를 실행하게 됩니다. 이는 함수 실행 순서가 코드상으로 존재하는 것과 일치하지 않는다는 뜻이므로 주의해야 합니다.

alert('aaa');

setTimeout('alert("bbb");', 3000);

alert('ccc');

예제에서는 aaa와 ccc를 출력한 뒤에 setTimeout함수를 실행하게 되므로 aaa -> ccc -> bbb 순서로 출력하게 됩니다.

for (var i = 0; i < 3; i++) {
	setTimeout(function() { alert(i); }, 1000);
}

상기 예제는 3을 세 번 출력합니다. for문의 반복문이 모두 실행되고 나서야 setTimeout을 실행하기 때문입니다. for가 실행을 완료하게 되면(자바스크립트가 for문 실행을 완료되게되면) i는 3이 되고 뒤에 실행되는 setTimeout함수에서 i값을 3번 그대로 출력하기 때문입니다.

 

(2) clearTimeout / clearInterval

 

clearTimeout은 setTimeout을 취소하고 clearInterval은 setInterval을 취소합니다. clearTimeout은 단 한 번만 수행하니 특별한 경우가 아니라면 거의 사용할 일이 없고 clearInterval이 자주 사용되는 편입니다.

var myfunc = function() {
	alert('실행됨');

	clearInterval(IntervalID);
};

var IntervalID = setInterval(myfunc, 3000);

setTimeout과 setInterval함수는 특별한 값을 반환하는데 이 값을 통해 clearTimeout과 clearInterval함수를 사용할 수 있습니다. 예제에서는 이 값을 IntervalID변수로 받아 함수가 실행되면 곧장 타이머 함수를 취소하도록 하였습니다.

 

(3) encodeURIComponent / decodeURIComponent

 

encodeURIComponent함수는 알파벳과 숫자를 제외하고 인수로 전달된 모든 문자를 인코딩하며 decodeURIComponent는 반대로 encodeURIComponent로 인코딩 된 내용을 디코딩하는 함수입니다.

var URI = 'http://cliel.com/테스트/01';
var eURI = encodeURIComponent(URI);
var dURI = decodeURIComponent(eURI);

alert(eURI);
alert(dURI);

위에서 설명한 함수 이외에 알파벳, 숫자, 일부 특수문자를 제외하고 인코딩과 디코딩을 수행하는 escape와 unescape함수도 있으며 escape에 더해서 URI를 구성하는데 필요한 문자(:, //... 등)를 추가적으로 제외하고 인코딩 와 디코딩을 수행하는 encodeURI와 decodeURI함수도 존재합니다.

 

(4) eval

 

함수 내부에 지정된 코드를 그대로 실행하는 함수 합니다.

var nm = '홍길동';
eval("alert('나의 이름은 " + nm + " 입니다.');");

eval은 주로 특정한 변수 등을 통해서 코드를 유동적으로 처리하고자 하는 경우에 종종 사용되며 심지어는 eval함수 내부에서 특정한 변수를 정의하는 것도 가능합니다.

 

(5) isFinite / isNaN

 

isFinite는 값이 유한한 수인지를 isNaN은 값이 NaN인지를 판별하는 함수입니다.

var v = 10 / 0;

if (!isFinite(v))
	alert('v는 Infinity');

var n = NaN;

if (isNaN(n))
	alert('n은 NaN');

자바스크립트에서 0으로 숫자를 나누면 결과로 Infinity, 즉 무한한 값이 됩니다. IsFinite는 값이 유한한 것인지 아닌지를 판별하므로 결과가 false라면 해당 값은 Infinity가 됩니다.

 

(6) parseInt / parseFloat

 

string형의 값을 parseInt함수는 정수로, parseFloat함수는 유리수로 변환합니다.

var ov = '1234';
var iv = parseInt(ov);

alert(iv);

예제에서 ov는 '1234'라는 문자열을 가진 변수입니다. 이 변수를 parseInt함수로 정수형의 데이터로 변환합니다.

비슷한 함수로 Number함수가 존재하지만 Number함수는 매개변수로 전달된 값자체를 숫자로 바꿀 수 없으면 NaN을 반환하지만 parseInt는 숫자로 바꿀 수 있는 값이라면 최대한 변환하고 결과를 반환합니다.

var ov = '1300원';
var iv = parseInt(ov); //1300
var tv = Number(ov); //'원'이라는 값은 숫자로 바꿀 수 없기에 NaN을 반환

alert(tv);

참고로 parseInt는 0으로 시작되는 값이면 8진수로, 0x로 시작하면 16진수로 인식하며 매개변수가 2개일 때 2번째 값을 진법으로 인식합니다.

alert(parseInt('ff', 16));

 

'Web > Javascript' 카테고리의 다른 글

[javascript] 함수  (0) 2020.03.27
[javascript] 반복문  (0) 2020.03.24
[javascript] 조건문  (0) 2020.03.17
[javascript] 기본 사항  (0) 2020.03.13
[javascript] 개요  (0) 2020.03.12

관련글 더보기

댓글 영역