일반적으로, 함수는 함수 외부 (또는 재귀(recursion)의 경우엔 내부) 코드에 의해 호출될 수 있는 "하위프로그램"입니다. 프로그램 그 자체처럼, 함수는 함수 몸통(function body)이라고 하는 일련의 구문(statement)으로 구성됩니다. 값은 함수에 전달될 수 있고 함수는 값을 반환합니다.

JavaScript에서, 함수는 다른 객체처럼 속성 및 메서드를 가질 수 있기에 일급(first-class) 객체입니다. 다른 객체와 함수를 구별하는 것은 함수는 호출될 수 있다는 것입니다. 간단히 말해, 함수는 Function 객체입니다.

더 많은 예제와 설명은, JavaScript 함수 안내서를 참조하세요.

설명

JavaScript에서 모든 함수는 Function 객체입니다. Function 객체의 속성(property) 및 메서드에 관한 정보는 Function 참조.

기본값 이외의 값을 반환하려면, 함수는 반환할 값을 지정하는 return 문이 있어야 합니다. return 문이 없는 함수는 기본값을 반환합니다. new 키워드로 호출되는 생성자의 경우에, 기본값은 자신의 this 매개변수 값입니다. 다른 모든 함수의 경우, 기본 반환값은 undefined입니다.

함수 호출의 매개변수는 함수의 인수입니다. 인수는 함수에 값으로 전달됩니다. 함수가 인수값을 바꾸면, 이 변화는 전역 또는 호출한 함수에 반영되지 않습니다. 그러나, 객체 참조(reference)는 값이지만 특별합니다: 함수가 참조된 객체의 속성을 바꾸면, 그 변화는 다음 예에서와 같이 함수 밖에서도 바뀌는 것을 볼 수 있습니다:

/* 함수 'myFunc' 선언 */
function myFunc(theObject) {
   theObject.brand = "Toyota";
 }

 /*
  * 변수 'mycar' 선언;
  * 새 객체를 만들고 초기화;
  * 'mycar'에 객체 참조를 할당
  */
 var mycar = {
   brand: "Honda",
   model: "Accord",
   year: 1998
 };

 /* Logs 'Honda' */
 console.log(mycar.brand);

 /* 객체 참조를 함수에 전달 */
 myFunc(mycar);

 /*
  * 함수에 의해 바뀌었기에 객체의
  * 'brand' 속성의 값으로 'Toyota' 출력.
  */
 console.log(mycar.brand);

this 키워드는 현재 실행 중인 함수를 참조하지 않습니다, 그래서 심지어 함수 몸통 내에서도 이름으로 Function 객체를 참조해야 합니다.

함수 정의하기

함수를 정의하는 여러 방법이 있습니다:

함수 선언 (function 문)

함수 선언을 위한 특별한 구문이 있습니다 (자세한 사항은 function 문 참조):

function name([param[, param[, ... param]]]) {
   statements
}
name
함수 이름.
param
함수에 전달되는 인수의 이름. 함수는 255개까지 인수를 가질 수 있습니다.
statements
함수의 몸통을 구성하는 문.

함수 표현식 (function 식)

함수 식(expression)은 함수 선언과 비슷하고 구문이 같습니다 (자세한 사항은 function 식 참조):

함수 표현식(expression)은 함수 선언과 비슷하고 구문을 같습니다 (자세한 내용은 function expression 참조). 함수 표현식은 더 큰 표현식의 일부일 수 있습니다. "이름이 붙은(named)"함수 표현식 (예 : 호출 스택에서 표현식 이름 사용하는경우) 또는 "익명"함수 표현식을 정의 할 수 있습니다. 함수 표현식은 선언이 되지 않은 상태에서 사용할 수 없기 때문에 함수를 사용하기 전에 코드에 함수코드가 존제해야 사용 할 수 있습니다.

function [name]([param[, param[, ... param]]]) {
   statements
}
name
함수 이름. 함수가 익명(anonymous) 함수로 알려진 경우, 생략될 수 있음.
param
함수에 전달되는 인수의 이름. 함수는 255개까지 인수를 가질 수 있습니다.
statements
함수의 몸통을 구성하는 문.

Here is an example of an anonymous function expression (the name is not used):

var myFunction = function() {
    statements
}

It is also possible to provide a name inside the definition in order to create a named function expression:

var myFunction = function namedFunction(){
    statements
}

One of the benefits of creating a named function expression is that in case we encountered an error, the stack trace will contain the name of the function, making it easier to find the origin of the error.

As we can see, both examples do not start with the function keyword. Statements involving functions which do not start with function are function expressions.

When functions are used only once, a common pattern is an IIFE (Immediately Invokable Function Expression).

(function() {
    statements
})();

IIFE are function expressions that are invoked as soon as the function is declared.

생성기 함수 선언 (function* 문)

생성기 함수 선언을 위한 특별한 구문이 있습니다 (자세한 사항은 function* statement 참조):

function* name([param[, param[, ... param]]]) {
   statements
}
name
함수 이름.
param
함수에 전달되는 인수의 이름.
statements
함수의 몸통을 구성하는 문.

생성기 함수 식 (function* 식)

생성기 함수 식은 생성기 함수 선언과 비슷하고 구문이 같습니다 (자세한 사항은 function* expression 참조):

function* [name]([param[, param[, ... param]]]) {
   statements
}
name
함수 이름. 함수가 익명 함수인 경우 생략될 수 있음.
param
함수에 전달되는 인수의 이름.
statements
함수의 몸통을 구성하는 문.

화살표 함수 표현식 (=>)

화살표 함수 식은 구문이 더 짧고 어휘상(lexically) this 값을 바인딩합니다 (자세한 사항은 화살표 함수 참조):

([param[, param]]) => {
   statements
}

param => expression
param
인수의 이름. 0개 인수는 ()로 표시돼야 합니다. 인수가 1개뿐이면, 괄호는 필요치 않습니다. (foo => 1처럼)
statements or expression
선언문이 여러개인 경우 괄호로 묶여야 합니다. 단일 식(expression)은 괄호가 필요 없습니다. 그리고 식은 암시적으로(implicit) 함수의 반환값이 됩니다.

Function constructor

참고 : Function constructor를 사용하여 함수를 만드는 것은 권장되지 않습니다. 함수 본문을 일부 JS 엔진 최적화를 방해 할 수있는 문자열로 사용해야하고 다른 문제를 유발할 수 있기 때문입니다.

다른 모든 객체처럼, Function 객체는 new 연산자를 사용하여 생성될 수 있습니다:

new Function (arg1, arg2, ... argN, functionBody)
arg1, arg2, ... argN
형식 매개변수로 함수에 의해 사용되는 0개 이상의 이름. 각각은 알맞은 JavaScript 식별자(identifier)여야 합니다.
functionBody
함수 몸통을 구성하는 JavaScript 문을 포함하는 문자열.

함수로 Function 생성자 호출(new 연산자 사용 없이)하는 것은 생성자로 호출하는 것과 같습니다.

GeneratorFunction 생성자

주의: GeneratorFunction은 전역 객체가 아니지만 생성기 함수 인스턴스로부터 얻을 수 있습니다(자세한 사항은 GeneratorFunction 참조).

주의: GeneratorFunction 생성자를 사용하여 함수를 만드는 것은 권장되지 않습니다. 함수 본문을 일부 JS 엔진 최적화를 방해 할 수있는 문자열로 사용해야하고 다른 문제를 유발할 수 있기 때문입니다.

다른 모든 객체처럼, GeneratorFunction 객체는 new 연산자를 사용하여 생성될 수 있습니다:

new GeneratorFunction (arg1, arg2, ... argN, functionBody)
arg1, arg2, ... argN
형식 인수명으로 함수에 의해 사용되는 0개 이상의 이름. 각각은 유효한 JavaScript 식별자 규칙을 따르는 문자열 또는 콤마로 구분된 그러한 문자열 목록이어야 합니다; 예를 들어 "x", "theValue" 또는 "a,b".
functionBody
함수 정의를 구성하는 JavaScript 문을 포함하는 문자열.

함수로서 Function 생성자 호출(new 연산자 사용 없이)은 생성자로서 호출하는 것과 같은 효과입니다.

Function 매개변수

기본 매개변수

기본(default) 함수 매개변수는 전달된 값이 없거나 undefined인 경우 기본값으로 초기화되는 형식 매개변수를 허용합니다. 자세한 사항은, 기본 매개변수 참조.

나머지 매개변수

나머지(rest) 매개변수 구문은 부정(indefinite)수인 인수를 배열로 나타내는 것을 허용합니다. 자세한 사항은, 나머지 매개변수 참조.

arguments 객체

arguments 객체를 사용하여 함수 내에서 함수의 인수를 참조할 수 있습니다. arguments 참조.

메서드 함수 정의하기

getter 및 setter 함수

모든 표준 내장 객체 또는 새로운 속성 추가를 지원하는 사용자 정의 객체에 getter(accessor 메서드) 및 setter(mutator 메서드)를 정의할 수 있습니다. getter 및 setter를 정의하는 구문은 객체 리터럴 구문을 사용합니다.

get

객체 속성을 그 속성이 검색되는 경우 호출되는 함수에 바인딩합니다.

set
객체 속성을 그 속성을 설정하려는 시도가 있는 경우 호출되는 함수에 바인딩합니다.

메서드 정의 구문

ECMAScript 2015를 시작으로, getter 및 setter와 비슷한 단축 구문으로 자신의 메서드를 정의할 수 있습니다. 더 자세한 정보는 메서드 정의 참조.

var obj = {
  foo() {},
  bar() {}
};

생성자 vs. 선언문 vs. 표현식

다음을 비교해보세요:

Function constructor로 정의된 함수를 변수multiply에 할당.

var multiply = new Function('x', 'y', 'return x * y');

이름이 multiply인 함수 선언:

function multiply(x, y) {
   return x * y;
}

변수 multiply에 할당된 익명(anonymous) 함수의 function 식:

var multiply = function(x, y) {
   return x * y;
};

변수 multiply에 할당된 이름이 func_name인 함수의 function 식:

var multiply = function func_name(x, y) {
   return x * y;
};

차이

모두 거의 같은 일을 하지만 약간 미묘한 차이가 있습니다:

함수 이름과 함수가 할당 된 변수 사이에는 차이가 있습니다. 함수 이름을 변경할 수 없으며 함수가 할당 된 변수는 다시 할당 할 수 있습니다. 함수 이름은 함수 본문(body)내에서만 사용할 수 있습니다. 함수 본문(body) 외부에서 사용하려고 하면 오류가 발생합니다. (함수 이름이 var 문을 통해 이전에 선언 된 경우에는 정의되지 않습(undefined)니다.

예를 들어:

var y = function x() {};
alert(x); // 오류 발생

함수 이름은 Function의 toString 메서드를 통해 직렬화되는 경우에도 보입니다.

반면에 함수가 할당 된 변수는 함수의 범위(scope)가 포함되도록 보장 된 범위로만 제한됩니다.

예제 4에서 볼 수 있듯이 함수 이름은 함수가 할당 된 변수와 다를 수 있습니다. 그들은 서로에게 아무런 관련이 없습니다. 함수 선언은 함수 이름과 동일한 이름의 변수도 만듭니다. 따라서 함수 표현식으로 정의 된 함수와 달리 함수 선언으로 정의 된 함수는 정의 된 범위에서 함수 선언의 이름으로 액세스 할 수 있습니다.

'new Function'으로 정의된 함수는 함수 이름이 없습니다. 그러나, SpiderMonkey JavaScript 엔진에서는, 함수의 직렬화된 형태가 마치 그 이름이 "anonymous"인 것처럼 보입니다. 예를 들어, alert(new Function())은 다음을 출력합니다:

function anonymous() {
}

함수가 실제로는 이름이 없기에, anonymous는 함수 내에서 액세스될 수 있는 변수가 아닙니다.

다음 코드는 오류가 날 것입니다:

var foo = new Function("alert(anonymous);");
foo();

function 식 또는 Function 생성자에 의해 정의된 함수와는 달리, function 선언으로 정의된 함수는 function 자체의 선언 전에 사용될 수 있습니다. 예를 들어:

foo(); // alerts FOO!
function foo() {
   alert('FOO!');
}

함수 표현식(function expression)이나 함수 선언(function declaration)에 의해 정의 된 함수는 현재 범위를 상속합니다. 즉,이 함수는 클로저를 형성합니다. 반면에 Function 생성자가 정의한 함수는 전역 범위 (모든 함수가 상속) 이외의 다른 범위를 상속하지 않습니다.

/*
 * Declare and initialize a variable 'p' (global)
 * and a function 'myFunc' (to change the scope) inside which
 * declare a varible with same name 'p' (current) and
 * define three functions using three different ways:-
 *     1. function declaration
 *     2. function expression
 *     3. function constructor
 * each of which will log 'p'
 */
var p = 5;
function myFunc() {
    var p = 9;

    function decl() {
        console.log(p);
    }
    var expr = function() {
        console.log(p);
    };
    var cons = new Function('\tconsole.log(p);');

    decl();
    expr();
    cons();
}
myFunc();

/*
 * Logs:-
 * 9  - for 'decl' by function declaration (current scope)
 * 9  - for 'expr' by function expression (current scope)
 * 5  - for 'cons' by Function constructor (global scope)
 */

function 식 및 function 선언에 의해 정의된 함수는 한 번만 구문 분석됩니다, 반면에 Function 생성자에 의해 정의된 함수는 아닙니다. 즉, Function 생성자에 전달된 함수 몸통 문자열은 생성자가 호출될 때마다 구문 분석되어야 합니다. function 식이 매번 closure를 만들더라도, 함수 몸통은 다시 구문 분석되지 않습니다, 그래서 function 식은 "new Function(...)"보다 여전히 더 빠릅니다. 따라서 Function 생성자는 보통 가능한 한 피해야 합니다.

함수 식과 함수 선언으로 정의 된 함수는 한 번만 구문 분석되지만 Function 생성자로 정의 된 함수는 구문 분석되지 않습니다. 즉, Function 생성자에 전달 된 함수 본문 문자열은 생성자가 호출 될 때마다 파싱되어야합니다. 함수식이 매번 클로저(closure)를 만들지만 함수 본문은 다시 파싱되지 않으므로 함수 식은 여전히 ​​"new Function (...)"보다 빠릅니다. 따라서 Function 생성자는 가능한 피하는 것이 좋습니다.

그러나 Function constructor의 문자열을 구문 분석하여 생성된 함수 내에 중첩된 function 식 및 function 선언은 반복해서 구문 분석되지 않음에 주의해야 합니다. 예를 들면:

var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
foo(); // 함수 몸통 문자열의 "function() {\n\talert(bar);\n}" 부분은 다시 구문 분석되지 않습니다.

function 선언은 매우 쉽게 (그리고 종종 무심코) function 식으로 바뀝니다. function 선언은 다음 어느 쪽이든 function 식이 되는 것을 중단합니다:

  • 식의 일부가 된 경우
  • 더 이상 함수 또는 스크립트 자체의 "source 요소"가 아닌 경우. "source 요소"는 스크립트 또는 함수 몸통에서 중첩되지 않은 문입니다:
var x = 0;               // source 요소
if (x == 0) {            // source 요소
   x = 10;               // source 요소가 아님
   function boo() {}     // source 요소가 아님
}
function foo() {         // source 요소
   var y = 20;           // source 요소
   function bar() {}     // source 요소
   while (y == 10) {     // source 요소
      function blah() {} // source 요소가 아님
      y++;               // source 요소가 아님
   }
}

// function 선언
function foo() {}

// function 식
(function bar() {})

// function 식
x = function hello() {}


if (x) {
   // function 식
   function world() {}
}


// function 선언
function a() {
   // function 선언
   function b() {}
   if (0) {
      // function 식
      function c() {}
   }
}

블록 레벨 함수

ES2015 (ES6)를 시작으로 엄격 모드에서, 블록 내부 함수는 이제 그 블록 범위가 됩니다. ES6 이전에, 블록 레벨 함수는 엄격 모드에서 금지됐습니다.

'use strict';

function f() { 
  return 1; 
}

{  
  function f() { 
    return 2; 
  }
}

f() === 1; // true

// 비엄격 모드에서는 f() === 2

비엄격 코드에서 블록 레벨 함수

한 마디로: 안됩니다.

비엄격 코드에서, 블록 내부 function 선언은 이상하게 동작합니다. 예를 들면:

if (shouldDefineZero) {
   function zero() {     // 위험: 호환성 위험
      console.log("This is zero.");
   }
}

ES2015는 shouldDefineZero가 false인 경우, 그러면 zero는 결코 정의되어서는 안된다고 합니다, 그 블록이 실행된 적이 없기에. 그러나, 이는 표준의 새로운 일부입니다. 역사상, 이는 지정되지 않은 채 방치되었고 일부 브라우저는 블록이 실행됐든 아니든 zero를 정의할 겁니다.

엄격 모드에서, ES2015를 지원하는 모든 브라우저는 이를 같은 식으로 다룹니다: zeroshouldDefineZero가 true이고 if 블록 범위인 경우에만 정의됩니다.

조건부 함수를 정의하는 더 안전한 방법은 function 식을 변수에 할당하는 것입니다:

var zero;
if (0) {
   zero = function() {
      console.log("This is zero.");
   };
}

예제

형식 갖춘 숫자 반환하기

다음 함수는 선행 0으로 채워진 형식 갖춘(formatted) 숫자 표현을 포함하는 문자열을 반환합니다.

// 이 함수는 선행 0으로 채워진 문자열을 반환
function padZeros(num, totalLen) {
   var numStr = num.toString();             // 문자열로 반환값을 초기화
   var numZeros = totalLen - numStr.length; // 0의 개수 계산
   for (var i = 1; i <= numZeros; i++) {
      numStr = "0" + numStr;
   }
   return numStr;
}

다음 문은 padZeros 함수를 호출합니다.

var result;
result = padZeros(42,4); // 반환값 "0042"
result = padZeros(42,2); // 반환값 "42"
result = padZeros(5,4);  // 반환값 "0005"

함수 존재 여부 결정하기

typeof 연산자를 사용하여 함수가 존재하는지 여부를 결정할 수 있습니다. 다음 예에서, window 객체가 함수인 noFunc이라고 하는 속성이 있는지 결정하기 위해 테스트가 수행됩니다. 있으면, 사용됩니다; 그렇지 않으면 무언가 다른 행동을 취합니다.

 if ('function' == typeof window.noFunc) {
   // noFunc() 사용
 } else {
   // 뭔가 다른 것 수행
 }

if 테스트에는, noFunc에 대한 참조가 사용되고—실제 함수가 호출되지 않도록 함수 이름 뒤에 괄호 "()"가 없음을 주의하세요.

명세

명세 상태 설명
ECMAScript 1st Edition (ECMA-262) Standard 초기 정의. JavaScript 1.0에서 구현됨
ECMAScript 5.1 (ECMA-262)
The definition of 'Function Definition' in that specification.
Standard
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Function definitions' in that specification.
Standard 신규: 화살표 함수, 생성기 함수, 기본 매개변수, 나머지 매개변수.
ECMAScript Latest Draft (ECMA-262)
The definition of 'Function definitions' in that specification.
Draft

브라우저 호환성

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
functionsChrome Full support YesEdge Full support YesFirefox Full support 1IE Full support YesOpera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesFirefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes
argumentsChrome Full support YesEdge Full support YesFirefox Full support 1IE Full support YesOpera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesFirefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes
Arrow functionsChrome Full support 45Edge Full support YesFirefox Full support 22
Notes
Full support 22
Notes
Notes The initial implementation of arrow functions in Firefox made them automatically strict. This has been changed as of Firefox 24. The use of 'use strict'; is now required.
Notes Prior to Firefox 39, a line terminator (\n) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES2015 specification and code like () \n => {} will now throw a SyntaxError in this and later versions.
IE No support NoOpera Full support 32Safari Full support 10WebView Android Full support 45Chrome Android Full support 45Firefox Android Full support 22
Notes
Full support 22
Notes
Notes The initial implementation of arrow functions in Firefox made them automatically strict. This has been changed as of Firefox 24. The use of 'use strict'; is now required.
Notes Prior to Firefox 39, a line terminator (\n) was incorrectly allowed after arrow function arguments. This has been fixed to conform to the ES2015 specification and code like () \n => {} will now throw a SyntaxError in this and later versions.
Opera Android Full support 32Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support Yes
Block-level functionsChrome ? Edge ? Firefox Full support 46IE ? Opera ? Safari ? WebView Android ? Chrome Android ? Firefox Android Full support 46Opera Android ? Safari iOS ? Samsung Internet Android ? nodejs ?
Default parametersChrome Full support 49Edge Full support 14Firefox Full support 15IE No support NoOpera Full support 36Safari Full support 10WebView Android Full support 49Chrome Android Full support 49Firefox Android Full support 15Opera Android Full support 36Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
Method definitionsChrome Full support 39Edge Full support YesFirefox Full support 34IE No support NoOpera Full support 26Safari Full support 9WebView Android Full support 39Chrome Android Full support 39Firefox Android Full support 34Opera Android Full support 26Safari iOS Full support 9Samsung Internet Android Full support 4.0nodejs Full support Yes
Rest parametersChrome Full support 47Edge Full support 12Firefox Full support 15IE No support NoOpera Full support 34Safari Full support 10WebView Android Full support 47Chrome Android Full support 47Firefox Android Full support 15Opera Android Full support 34Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support 6.0.0
Full support 6.0.0
Full support 4.0.0
Disabled
Disabled From version 4.0.0: this feature is behind the --harmony runtime flag.
getChrome Full support 1Edge Full support YesFirefox Full support 2IE Full support 9Opera Full support 9.5Safari Full support 3WebView Android Full support 1Chrome Android Full support 18Firefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes
setChrome Full support 1Edge Full support YesFirefox Full support 2IE Full support 9Opera Full support 9.5Safari Full support 3WebView Android Full support 1Chrome Android Full support 18Firefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
See implementation notes.
See implementation notes.
User must explicitly enable this feature.
User must explicitly enable this feature.

같이 보기

문서 태그 및 공헌자

이 페이지의 공헌자: limkukhyun, alattalatta, mdnwebdocs-bot, Netaras, sftblw
최종 변경자: limkukhyun,