본문 바로가기
WEB/JavaScript

[JavaScript] 자바스크립트 기초 문법 - 함수

by Amy IT 2022. 6. 27.

 

함수란 어떤 작업을 수행하기 위해 필요한 문(statement)들의 집합을 정의한 코드 블록입니다. 함수를 정의한 후 호출함으로써 코드 블록에 담긴 문들을 일괄적으로 실행할 수 있습니다.

 

목차

     

    함수 정의

    함수를 정의하는 방법 두 가지를 살펴보겠습니다. 

     

    함수 선언문

    첫 번째는 선언적 정의 방법으로, 이름이 있는 일반적인 함수를 정의할 수 있습니다. 함수 선언문에서 함수명은 생략할 수 없습니다.

    함수는 매개변수와 리턴값을 가질 수 있습니다. 인자를 전달받지 않으면 매개변수는 undefined로 초기화되며, 반환을 생략하면 함수는 undefined를 반환합니다.

    function 함수명( [매개변수1,매개변수2,..] ){
          문장;
          [return 리턴값;]
    }

     

    함수 표현식

    두 번째는 함수 리터럴 방식으로 함수를 정의하고 변수에 할당하는 방법으로, 함수명을 생략한 익명 함수를 정의할 수 있습니다. 

    var 변수명= function ( [매개변수1,매개변수2,..] ){
          문장;
          [return 리턴값;]
    }

     

     

     

    함수 호이스팅 (Function Hoisting)

    호이스팅(Hoisting)이란 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성을 말합니다. 자바스크립트는 모든 선언(var, let, const, function, class)을 호이스팅하기 때문에 선언 이전에 참조가 가능합니다. 그런데 함수 선언문과 함수 표현식의 동작 방식에는 차이가 있습니다.

     

    함수 선언문으로 정의된 함수는 스크립트가 로딩되는 시점에 바로 초기화되고 VO(variable object)에 저장됩니다. 즉, 함수 선언, 초기화, 할당이 한번에 이루어집니다. 따라서 함수 호이스팅에 의해 함수 선언 전 호출이 가능합니다.

    a();
    function a() {
    	console.log("a() 호출됨");
    }

     

    하지만 함수 표현식으로 정의된 함수는 스크립트 로딩 시점에 변수 객체(VO)에 함수를 할당하지 않고 runtime에 해석되고 실행됩니다. 이 경우 함수 호이스팅이 아닌 변수 호이스팅이 발생하여 TypeError가 발생합니다. 호이스팅된 변수는 undefined로 초기화된 상태이며, 실제 값의 할당은 할당문에서 이루어지게 됩니다. 

    f(); //TypeError: f is not a function
    var f = function() {
    	console.log("익명함수 호출됨");
    }

     

     

     

    함수 매개변수(parameter)와 인자(argument)

    자바스크립트는 함수 호출 시 함수 정의에 따라 인자를 전달하지 않아도 에러가 발생하지 않습니다. 매개변수의 개수보다 인자를 적게 전달했을 때 인자가 전달되지 않은 매개변수는 undefined으로 초기화되며, 매개변수의 개수보다 인자를 더 많이 전달했을 때 초과된 인자는 무시됩니다. 

    function aaa(n, n2) { //매개변수 두개
    	console.log(n, n2);
    }
    aaa(); //undefined  undefined
    aaa(10); //10  undefined 
    aaa(10,20); //10  20
    aaa("홍길동", "이순신", "유관순"); //홍길동  이순신

     

    자바스크립트는 함수를 호출할 때 인자들과 함께 암묵적으로 arguments 객체가 함수 내부로 전달됩니다. arguments 객체는 함수 호출 시 전달된 인자들의 정보를 담고 있는 순회가능한(iterable) 유사 배열 객체(array-like object)이며 함수 내부에서 지역변수처럼 사용됩니다. 매개변수 개수가 확정되지 않은 가변 인자 함수를 구현할 때 유용하게 사용할 수 있습니다.

    function sum() {
    	var result = 0;
    	for (var i = 0; i < arguments.length; i++) {
    		result += arguments[i];
    	}
    	return result;
    }
    console.log(sum()); //0
    console.log(sum(1, 2)); //3
    console.log(sum(1, 2, 3)); //6

     

     

     

    일급 객체 (First-class object)

    자바스크립트의 함수는 일급 객체입니다. 일급 객체란 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킵니다. 일급 객체의 특징은 다음과 같습니다.

     

    1. 변수에 저장(할당) 가능합니다.
    2. 매개변수에 전달 가능합니다.
    3. 리턴값으로 사용 가능합니다.

     

    변수에 저장 가능

    함수명에 괄호를 붙이지 않고 사용하면 함수를 변수에 저장할 수 있게 됩니다. num 변수의 경우 a 함수를 호출한 후 반환받은 100 값이 저장되는 반면, x 변수의 경우 a 함수 객체의 참조값이 저장됩니다. 따라서 x와 a가 동일한 함수를 가리키게 되어, x를 출력하면 a 함수 전체가 출력되고 x() 로 호출하면 a() 로 호출한 것과 동일한 결과가 나타납니다.

    function a() {
    	console.log("a() 호출됨");
    	return 100;
    }
    var num = a(); //함수 호출 후 리턴값 받아서 저장
    var x = a; //함수 객체를 변수에 저장 
    console.log(num); //100 출력
    console.log(x); //a() 함수 전체 출력
    x(); //x변수 이용, 함수 호출

     

    매개변수에 전달 가능

    함수 호출시 매개변수로 함수를 전달할 수 있습니다. 이때 함수는 객체이므로 객체의 참조값이 인자로 전달됩니다. 아래 예시에서 b 함수를 호출하며 매개변수에 a 함수를 전달하고 있습니다. 매개변수 x에는 a 함수의 참조값이 저장되어, x와 a가 동일한 함수 객체를 참조하게 됩니다.

    function a() {
    	console.log("a() 호출됨");
    	return 100;
    }
    function b(x) { //a 함수 전달받음, x = a 
    	console.log("b() 호출됨", x); //a 함수 전체 출력
    	console.log("b() 안에서:", x()); //a 함수 호출, 리턴값 100 출력
    }
    b(a); //b() 호출하며 매개변수에 a 함수 전달
    //b(a()); //b() 호출하며 매개변수에 100 전달 //TypeError: x is not a function

     

    익명함수를 직접 정의하여 매개변수로 전달할 수도 있습니다.

    b(
    	function () {
    		console.log("익명함수 호출");
    		return 200;
    	}
    );

     

    리턴값으로 사용 가능

    함수의 리턴값으로 함수를 리턴할 수 있습니다. b() 로 b 함수를 호출한 후 a 함수를 리턴받아 x 변수에 저장하고 있습니다. bb 함수의 경우 리턴값이 a 함수를 호출한 리턴값이므로 num 변수에는 100이 저장됩니다. 

    function a() {
    	console.log("a() 호출됨");
    	return 100;
    }
    function b() {
    	console.log("b() 호출됨");
    	return a; //a 함수를 리턴
    }
    function bb() {
    	console.log("bb() 호출됨");
    	return a(); //a 함수 호출 후 100 리턴받고 다시 리턴
    }
    var x = b(); //b 함수 호출 후 a 함수 리턴받아 저장
    console.log(x); //a 함수 출력
    x(); //a 함수 호출 
    var num = bb(); //bb 함수 호출 후 100 리턴받아 저장
    console.log(num); //100 출력
    //num(); //TypeError: num is not a function

     

    리턴값으로 익명함수를 직접 정의하여 사용할 수도 있습니다.

    function c() {
    	return function (n1, n2) { //익명함수 리턴
    		return n1+n2;
    	};
    }
    var y = c(); //c 함수 호출 후 익명함수 리턴받아 저장
    console.log(y); //익명함수 출력 
    var result = y(10,20); //익명함수 호출 후 30 리턴받아 저장
    console.log(result); //30 출력

     

     

     

    함수의 다양한 형태

    즉시 실행 함수 (IIFE, Immediately Invoke Function Expression)

    함수의 정의와 동시에 실행되는 함수로서, 최초 한번만 호출되며 다시 호출할 수 없습니다.

    (함수 구현)();
    (function () {
    	console.log("즉시실행함수");
    })();
    (function (n) {
    	console.log("즉시실행", n);
    })(10);

     

    중첩 함수 (Nested function)

    함수 내부에 함수를 정의한 형태로서, 특정 함수 내부에서만 사용하는 기능일 경우 외부에 노출시키지 않고 내부에 정의해서 사용할 수 있습니다. 또한, 내부함수에서는 부모함수의 변수에 접근할 수 있지만, 부모함수에서는 내부함수(자식함수)의 변수에 접근할 수 없습니다. 

    var a = function (arg) { //② 2 받음 
    	var b = function (n) {
    		return n*100; //④ 2 받아서 200 리턴  
    	}
    	return b(arg); //③ b함수 호출하며 2 전달 //⑤ 200리턴
    }
    
    var result = a(2); //① a 함수 호출하며 2 전달 //⑥ 200 리턴 받아 저장 
    console.log(result); //200

     

    콜백 함수 (Callback function)

    특정 함수 호출시 트리거(trigger) 형태로 다른 함수를 호출하는 형태로서, 이벤트 처리시 매우 많이 사용되는 구조입니다. 함수 호출시 콜백함수값을 인자로 전달하여 호출함수 내에서 콜백함수가 호출되도록 합니다. 

    function call(info) {
    	info(); //함수 호출
    }
    var callback = function () {
    	console.log("callback");
    }
    call(callback);

     

     

     

    참고

    https://poiemaweb.com/js-function

     

     

     

     

    댓글