[Javascript] ν•¨μˆ˜(function)

nxnaxxΒ·2021λ…„ 11μ›” 13일
0

javascript

λͺ©λ‘ 보기
8/14
post-thumbnail

ν•¨μˆ˜(function)

Β ν•¨μˆ˜λŠ” 일련의 과정을 statement둜 κ΅¬ν˜„ν•˜κ³  μ½”λ“œ λΈ”λ‘μœΌλ‘œ 감싸 ν•˜λ‚˜μ˜ μ‹€ν–‰ λ‹¨μœ„λ‘œ μ •μ˜ν•œ 것이닀. ν•¨μˆ˜λŠ” μž…λ ₯을 λ°›μ•„ 좜λ ₯을 λ‚΄λ³΄λ‚΄λŠ”λ°, μ΄λ•Œ ν•¨μˆ˜ λ‚΄λΆ€λ‘œ μž…λ ₯을 μ „λ‹¬λ°›λŠ” λ³€μˆ˜λ₯Ό λ§€κ°œλ³€μˆ˜(parameter), μž…λ ₯을 인수(argument), 좜λ ₯을 λ°˜ν™˜κ°’(return value)이라 ν•œλ‹€.

ν•¨μˆ˜λŠ” ν•¨μˆ˜ μ •μ˜(function definition)λ₯Ό 톡해 μƒμ„±ν•˜κ³  ν•¨μˆ˜ 호좜(function call)을 ν•˜λ©΄ μ½”λ“œ 블둝에 λ‹΄κΈ΄ statement듀이 μΌκ΄„μ μœΌλ‘œ μ‹€ν–‰λ˜κ³  λ°˜ν™˜κ°’μ„ λ°˜ν™˜ν•œλ‹€.

πŸ’‘ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 이유?

  • ν•¨μˆ˜λŠ” λͺ‡ λ²ˆμ΄λ“  ν˜ΈμΆœν•  수 μžˆμ–΄ μ½”λ“œ μž¬μ‚¬μš© μΈ‘λ©΄μ—μ„œ μœ μš©ν•˜λ‹€.
  • μœ μ§€λ³΄μˆ˜μ˜ νŽΈμ˜μ„±μ„ 높이고 μ‹€μˆ˜λ₯Ό 쀄여 μ½”λ“œμ˜ 신뒰성을 높인닀.
  • μ μ ˆν•œ ν•¨μˆ˜ 이름을 뢙이면 λ‚΄λΆ€ μ½”λ“œλ₯Ό μ΄ν•΄ν•˜μ§€ μ•Šκ³ λ„ 역할을 νŒŒμ•…ν•  수 있기 λ•Œλ¬Έμ— μ½”λ“œμ˜ 가독성을 ν–₯μƒμ‹œν‚¨λ‹€.

βœ” 이상적인 ν•¨μˆ˜λŠ” ν•œ 가지 일만 ν•˜κ³  가급적 μž‘κ²Œ λ§Œλ“œλŠ” 것이 μ’‹λ‹€.
βœ” λ§€κ°œλ³€μˆ˜λŠ” μ΅œλŒ€ 3개 이상을 λ„˜μ§€ μ•ŠλŠ” 것을 ꢌμž₯ν•œλ‹€.


ν•¨μˆ˜ μ •μ˜

ν•¨μˆ˜ μ„ μ–Έλ¬Έ(function declaration)

Β ν•¨μˆ˜ 선언문은 ν•¨μˆ˜ λ¦¬ν„°λŸ΄κ³Ό ν˜•νƒœκ°€ λ™μΌν•˜μ§€λ§Œ λ¦¬ν„°λŸ΄κ³Ό 달리 ν•¨μˆ˜ 이름을 μƒλž΅ν•  수 μ—†λ‹€. λ˜ν•œ, ν•¨μˆ˜ 선언문은 ν‘œν˜„μ‹μ΄ μ•„λ‹ˆλΌ 문이닀.

// function declaration
function add(a, b) {
  return a + b;
}

console.dir(add); // console.dir은 ν•¨μˆ˜ 객체의 ν”„λ‘œνΌν‹°κΉŒμ§€ 좜λ ₯
console.log(add(4, 6));

[μ‹€ν–‰κ²°κ³Ό]
[Function: add]
10

πŸ’‘ ν‘œν˜„μ‹μΈ λ¬Έ VS ν‘œν˜„μ‹μ΄ μ•„λ‹Œ λ¬Έ
ν‘œν˜„μ‹μΈ 문은 κ°’μœΌλ‘œ ν‰κ°€λ˜λ―€λ‘œ λ³€μˆ˜μ— ν• λ‹Ήν•  수 μžˆλ‹€. ν‘œν˜„μ‹μ΄ μ•„λ‹Œ 문은 κ°’μœΌλ‘œ ν‰κ°€λ˜μ§€ μ•Šμ•„ λ³€μˆ˜μ— ν• λ‹Ήν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.


ν•¨μˆ˜ ν‘œν˜„μ‹(function expression)

Β ν•¨μˆ˜λŠ” κ°’μ˜ μ„±μ§ˆμ„ κ°–λŠ”λ°, μ΄λŸ¬ν•œ 객체λ₯Ό 일급 객체(first-class object)라고 ν•œλ‹€. ν•¨μˆ˜ 객체λ₯Ό λ³€μˆ˜μ— ν• λ‹Ήν•˜λŠ” 방식을 ν•¨μˆ˜ ν‘œν˜„μ‹μ΄λΌκ³  ν•œλ‹€.

// function expression
var sub = function (x, y) { // ν•¨μˆ˜ ν‘œν˜„μ‹μ˜ ν•¨μˆ˜ λ¦¬ν„°λŸ΄μ€ ν•¨μˆ˜ 이름을 μƒλž΅ν•˜λŠ” 것이 일반적
  return x - y; 
};

console.log(sub(10, 5));

[μ‹€ν–‰κ²°κ³Ό]
5

ν•¨μˆ˜ 생성 μ‹œμ κ³Ό ν˜Έμ΄μŠ€νŒ…(hoisting)

Β ν•¨μˆ˜ μ„ μ–Έλ¬ΈμœΌλ‘œ μ •μ˜ν•œ ν•¨μˆ˜λŠ” μ„ μ–Έλ¬Έ 이전에 ν˜ΈμΆœν•  수 μžˆλ‹€. κ·ΈλŸ¬λ‚˜ ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œ μ •μ˜ν•œ ν•¨μˆ˜λŠ” ν‘œν˜„μ‹ 이전에 ν˜ΈμΆœν•  수 μ—†λ‹€.

// function declaration VS function expression
// function call
console.log(declAdd(4, 6)); // 10
console.log(expAdd(4, 6)); // TypeError

function declAdd(x, y) {
  return x + y;
}

var expAdd = function (x, y) {
  return x + y;
};

ν•¨μˆ˜ 선언문은 λŸ°νƒ€μž„(runtime) 이전에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ ν•¨μˆ˜ 객체가 λ¨Όμ € μƒμ„±λ˜κ³  ν•¨μˆ˜ 이름과 λ™μΌν•œ μ΄λ¦„μ˜ μ‹λ³„μžλ₯Ό μ•”λ¬΅μ μœΌλ‘œ μƒμ„±ν•˜κ³  객체λ₯Ό ν• λ‹Ήν•œλ‹€. κ·Έλž˜μ„œ ν•¨μˆ˜ μ„ μ–Έλ¬Έ 이전에 ν•¨μˆ˜λ₯Ό μ°Έμ‘°ν•  수 있고 ν˜ΈμΆœν•  μˆ˜λ„ μžˆλŠ” 것이닀.

이처럼 ν•¨μˆ˜ 선언문이 μ½”λ“œ μ„ λ‘λ‘œ λŒμ–΄ μ˜¬λ €μ§„ κ²ƒμ²˜λŸΌ λ™μž‘ν•˜λŠ” νŠΉμ§•μ„ ν•¨μˆ˜ ν˜Έμ΄μŠ€νŒ…(function hoisting)이라 ν•œλ‹€.

반면, ν•¨μˆ˜ ν‘œν˜„μ‹μ—μ„œλŠ” λ³€μˆ˜ 선언이 λŸ°νƒ€μž„ 이전에 μ‹€ν–‰λ˜μ–΄ undefined둜 μ΄ˆκΈ°ν™”λ˜λ‚˜ ν•¨μˆ˜ λ¦¬ν„°λŸ΄μ€ 할당문이 μ‹€ν–‰λ˜λŠ” μ‹œμ μ— ν‰κ°€λœλ‹€. κ·Έλž˜μ„œ ν•¨μˆ˜λ₯Ό ν‘œν˜„μ‹λ³΄λ‹€ λ¨Όμ € ν˜ΈμΆœν•˜λ©΄ undefinedλ₯Ό ν˜ΈμΆœν•˜λŠ” 것과 κ°™μœΌλ―€λ‘œ TypeErrorκ°€ λ°œμƒν•˜κ²Œ λ˜λŠ” 것이닀.

πŸ“Œ λ³€μˆ˜ μ„ μ–Έ
var ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œ λ³€μˆ˜ 선언은 undefined둜 암묡적인 μ΄ˆκΈ°ν™”κ°€ μˆ˜ν–‰λ¨.


ν™”μ‚΄ν‘œ ν•¨μˆ˜(arrow function)

Β function ν‚€μ›Œλ“œ λŒ€μ‹  ν™”μ‚΄ν‘œ =>λ₯Ό μ‚¬μš©ν•΄ κ°„λž΅ν•˜κ²Œ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•  수 μžˆλ‹€.

// arrow function
const div = (x, y) => x / y;

console.log(div(10, 8));

[μ‹€ν–‰κ²°κ³Ό]
1.25

λ‹€μ–‘ν•œ ν•¨μˆ˜ ν˜•νƒœ

μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜(IIFE, Immediately Invoked Function Expression)

Β μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λŠ” ν•¨μˆ˜ μ •μ˜μ™€ λ™μ‹œμ— μ¦‰μ‹œ ν˜ΈμΆœλ˜λŠ”λ° 단 ν•œ 번만 호좜되며 λ‹€μ‹œ ν˜ΈμΆœν•  수 μ—†λ‹€. 일반 ν•¨μˆ˜μ²˜λŸΌ 값을 λ°˜ν™˜ν•  수 있고 인수 전달도 κ°€λŠ₯ν•˜λ‹€.

// IIFE
(function () {
  var x = 8;
  var y = 5;
  return x * y;
}());

var immed = (function () {
  var x = 8;
  var y = 5;
  return x * y;
}());

console.log(immed);

immed = (function (a, b) {
  return a * b;
}(8, 5));

console.log(immed);

[μ‹€ν–‰κ²°κ³Ό]
40
40

이처럼 μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜ 내에 μ½”λ“œλ₯Ό λͺ¨μ•„두면 ν˜Ήμ‹œλΌλ„ μ‘΄μž¬ν•˜κ³  μžˆλŠ” λ³€μˆ˜λ‚˜ ν•¨μˆ˜ μ΄λ¦„μ˜ μΆ©λŒμ„ 방지할 수 μžˆλ‹€.


μž¬κ·€ ν•¨μˆ˜(recursive function)

 자기 μžμ‹ μ„ ν˜ΈμΆœν•˜λŠ” ν–‰μœ„λ₯Ό μž¬κ·€ 호좜(recursive call)이라고 ν•œλ‹€. μž¬κ·€ ν•¨μˆ˜λŠ” μž¬κ·€ ν˜ΈμΆœμ„ μˆ˜ν–‰ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ§ν•˜λ©° λ°˜λ³΅λ˜λŠ” 처리λ₯Ό μœ„ν•΄ μ‚¬μš©ν•œλ‹€.

μž¬κ·€ ν•¨μˆ˜λŠ” μžμ‹ μ„ λ¬΄ν•œ μž¬κ·€ ν˜ΈμΆœν•˜λ―€λ‘œ λ°˜λ“œμ‹œ ν•¨μˆ˜ 내에 νƒˆμΆœ 쑰건(escape condition)을 μ„€μ •ν•΄μ•Ό ν•œλ‹€. νƒˆμΆœ 쑰건이 μ—†μœΌλ©΄ stack overflow μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

// recursive function
function countDown(num) {
  if (num === 0) return ; // νƒˆμΆœ 쑰건
  console.log(num);
  countDown(num - 1);
}

countDown(5);

[μ‹€ν–‰κ²°κ³Ό]
5
4
3
2
1

ex) νŒ©ν† λ¦¬μ–Ό μž¬κ·€ ν•¨μˆ˜

function fact(n) {
  if (n === 1) return 1;
  return n * fact(n - 1);
}
> 
console.log(`1! = ${fact(1)}`);
console.log(`2! = ${fact(2)}`);
console.log(`3! = ${fact(3)}`);
console.log(`4! = ${fact(4)}`);
console.log(`5! = ${fact(5)}`);
> 
[μ‹€ν–‰κ²°κ³Ό]
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120

βœ” μž¬κ·€ ν•¨μˆ˜λŠ” 반볡문 없이 λ°˜λ³΅λ˜λŠ” 처리λ₯Ό κ΅¬ν˜„ν•  수 μžˆμœΌλ‚˜, λ¬΄ν•œ 루프에 빠질 수 μžˆμœΌλ―€λ‘œ μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. λ•Œλ¬Έμ— λ°˜λ³΅λ¬Έλ³΄λ‹€ μ§κ΄€μ μœΌλ‘œ μ΄ν•΄ν•˜κΈ° μ‰¬μšΈ λ•Œλ§Œ ν•œμ •μ μœΌλ‘œ μ‚¬μš©ν•˜λŠ” 것이 μ’‹λ‹€.


쀑첩 ν•¨μˆ˜(nested function)

 쀑첩 ν•¨μˆ˜λŠ” ν•¨μˆ˜ 내뢀에 μ •μ˜λœ ν•¨μˆ˜λ₯Ό λœ»ν•˜λ©°, λ‚΄λΆ€ ν•¨μˆ˜(inner function)라고도 ν•œλ‹€. 그리고 쀑첩 ν•¨μˆ˜λ₯Ό 감싸고 μžˆλŠ” ν•¨μˆ˜λ₯Ό μ™ΈλΆ€ ν•¨μˆ˜(outer function)라고 λΆ€λ₯Έλ‹€. 쀑첩 ν•¨μˆ˜λŠ” μ™ΈλΆ€ ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ ν˜ΈμΆœν•  수 μžˆλ‹€.

// nested function
function outer() { // outer function
  var a = 5;

  function inner() { // inner function
    var b = 3;
    console.log(a + b);
  }

  inner();
}

outer();

[μ‹€ν–‰κ²°κ³Ό]
8

콜백 ν•¨μˆ˜(callback function)

Β ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 λ‹€λ₯Έ ν•¨μˆ˜μ˜ λ‚΄λΆ€λ‘œ μ „λ‹¬λ˜λŠ” ν•¨μˆ˜λ₯Ό 콜백 ν•¨μˆ˜(callback function)라고 ν•œλ‹€. λ˜ν•œ λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ 콜백 ν•¨μˆ˜λ₯Ό 전달받은 ν•¨μˆ˜λ₯Ό κ³ μ°¨ ν•¨μˆ˜(HOF, Higher-Order Function)라고 λΆ€λ₯Έλ‹€.

// callback function
function odd(num, cb) {
  for (i = 1; i < num; i++) {
    cb(i);
  }
}

var high = function (i) {
  if (i % 2 !== 0) console.log(i);
};

odd(10, high);

[μ‹€ν–‰κ²°κ³Ό]
1
3
5
7
9

μœ„ μ½”λ“œμ—μ„œμ²˜λŸΌ odd ν•¨μˆ˜ 반볡문 λ‚΄λΆ€μ—μ„œ λ‹€λ₯Έ 일을 ν•˜κ³  μ‹Άλ‹€λ©΄ ν•¨μˆ˜λ₯Ό μƒˆλ‘­κ²Œ μ •μ˜ν•΄μ•Ό ν•˜μ§€λ§Œ 콜백 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ 뢄리가 κ°€λŠ₯ν•˜λ‹€.

ν•¨μˆ˜μ˜ λ³€ν•˜μ§€ μ•ŠλŠ” 곡톡적인 둜직(= odd)은 미리 μ •μ˜ν•΄ 두고 κ²½μš°μ— 따라 λ³€κ²½λ˜λŠ” 둜직(= high)은 κ³ μ°¨ ν•¨μˆ˜μ™€ 같이 μ™ΈλΆ€μ—μ„œ μ „λ‹¬λ°›μœΌλ©΄ 맀번 ν•¨μˆ˜λ₯Ό μ •μ˜ν•΄μ•Ό ν•˜λŠ” λ²ˆκ±°λ‘œμ›€μ„ 쀄일 수 μžˆλ‹€.

2개의 λŒ“κΈ€

comment-user-thumbnail
2023λ…„ 3μ›” 8일

I liked the idea, it's expected that all this luxury will be from this beautiful game Candy Crush

λ‹΅κΈ€ 달기
comment-user-thumbnail
2023λ…„ 4μ›” 11일

Nice blog.

λ‹΅κΈ€ 달기