웹 서비스 개발(FB,BE,SERVER,DB)/Javascript

3. 함수

Zoo_10th 2024. 3. 6.

1. 함수

1-1. JavaScript의 함수

함수(function)은 프로그램에서 특정 작업을 수행하기 위한 명령문의 집합이다. 함수는 프로그램의 기본 구성 요소 중 하나이며, 코드를 모듈화하고 재사용 가능한 단위로 분리하는 데 사용된다.

1-1-1. 함수의 기본 형태

function functionName(param1, param2) {
  // 함수의 몸체 (실행될 코드)
  return returnValue; // 옵션: 값을 반환할 수 있음
}

1) function : 함수를 정의할 때 사용하는 키워드다.

2) functionName : 함수의 이름을 지정한다.

3) param1, param2 : 함수의 매개변수(parameters)로, 함수가 실행될 때 입력값을 받는다.

4) {...} : 함수의 몸체(body)로, 함수가 수행할 작업을 포함한다.

5) return : 함수가 값을 반환할 때 사용하는 키워드다. 필요한 경우에만 사용하며, 값을 반환하지 않을 수도 있다.

// 함수 정의: printHello 함수는 매개변수 없이 'Hello'를 출력합니다.
function printHello() {
  console.log('Hello');
}

// 함수 호출: printHello 함수를 호출하여 'Hello'를 출력합니다.
printHello();

// 함수 정의: log 함수는 매개변수로 전달된 메시지를 출력합니다.
function log(message) {
  console.log(message);
}

// 함수 호출: log 함수를 호출하여 'Hello@'를 출력합니다.
log('Hello@');

1-2. 매개변수(Parameter)

JavaScript에서 함수의 매개변수(parameters)를 통해 값이 전달되는 방식은 기본 자료형과 참조 자료형(객체) 사이에 차이가 있다.

1-2-1. 기본 자료형 (값 전달)

function changeName(name) {
  name = 'tom';
}

const name = 'john';
changeName(name);
console.log(name);

changeName 함수는 name이라는 문자열 변수를 매개변수로 받아 그 값을 'tom'으로 변경하려고 한다. 그러나 이 코드에서 name 변수의 값은 함수 내에서 변경되지 않는다. JavaScript에서는 기본 자료형 변수(문자열, 숫자, 불리언 등)를 함수로 전달할 때 해당 변수의 값만 복사되어 전달되므로 함수 내에서 변경해도 외부 변수에는 영향을 미치지 않는다. 따라서 console.log(name)의 결과는 'john'으로 출력된다.

1-2-2. 참조 자료형 (객체) - 참조(주소) 전달

function changeNameByObject(obj) {
  obj.name = 'tom';
}

const user = { name: 'john' };
changeNameByObject(user);
console.log(user);

changeNameByObject 함수는 객체 user를 매개변수로 받아 그 객체의 name 속성 값을 'tom'으로 변경한다. 이 경우, JavaScript에서는 객체는 참조(주소)로 전달되므로 함수 내에서 객체의 속성을 변경하면 외부 변수에도 영향을 미친다. 따라서 console.log(user)의 결과는 { name: 'tom' }으로 출력된다.

1-2-3. 기본값 지정

function showMessage(message, from = 'unknown') {
  console.log(`${message} by ${from}`);
}

showMessage('Hi!'); // "Hi! by unknown" 출력

showMessage 함수는 message와 from 두 개의 매개변수를 가진다. 그런데 from 매개변수에 기본값으로 'unknown'을 지정했다. 이렇게 기본값을 지정하면 함수를 호출할 때 해당 매개변수에 값을 전달하지 않으면 기본값이 사용된다. 위 예제에서는 from 매개변수를 지정하지 않았으므로 'unknown'이 출력된다.

1-2-4. 가변 인자 (Rest Parameter)

function printAll(...args) {
  for (let i = 0; i < args.length; i++) {
    console.log(args[i]);
  }
}

printAll('java', 'script', 'html/css');

printAll 함수는 가변 인자로서 ...args를 사용하고 있다. 이렇게 하면 함수를 호출할 때 여러 개의 인자를 전달할 수 있고, 이 인자들은 배열 형태로 args 변수에 저장된다. 따라서 printAll 함수는 인자의 개수에 상관없이 모든 인자를 출력한다.

1-3. 전역변수 지역변수

JavaScript에서 변수의 유효 범위(scope)는 변수가 어디서 접근 가능한지를 나타낸다. 변수의 유효 범위는 변수를 선언한 위치와 관련이 있다.

let globalMessage = 'global'; // 전역 변수 (global variable)

function printMessage() {
  let message = 'hello'; // 지역 변수 (local variable)
  console.log(message); // 함수 내에서 지역 변수 출력
  console.log(globalMessage); // 함수 내에서 전역 변수 출력
}

printMessage(); // 함수 호출

console.log(message); // Error: message is not defined (지역 변수는 함수 외부에서 접근 불가)
console.log(globalMessage); // 전역 변수는 함수 외부에서 접근 가능

globalMessage 변수는 전역 범위에서 선언되었으므로 함수 내부에서도 외부에서도 접근 가능하다. 하지만 message 변수는 printMessage 함수 내에서만 선언되었으며 함수 내부에서만 접근 가능한 지역 변수다. 함수 외부에서 message 변수에 접근하려고 하면 "Error: message is not defined" 에러가 발생한다.

1-3-1. Return

function sum(a, b) {
  return a + b;
}

const result = sum(1, 2); // 함수 호출 결과를 result 변수에 저장
console.log(`sum: ${sum(1, 2)}`); // 함수 호출 결과를 직접 출력

function nothing(a, b) {
  // 아무런 값을 반환하지 않음
}

console.log(`result: ${nothing(1, 2)}`); // 함수가 아무런 값을 반환하지 않으므로 undefined 출력

sum 함수는 두 개의 매개변수 a와 b를 받아서 더한 결과를 return 키워드를 사용하여 반환한다. 함수를 호출하면 반환된 결과를 변수에 저장하거나 직접 출력할 수 있다.

nothing 함수는 아무런 값을 반환하지 않으며, 함수가 아무런 값을 반환하지 않을 경우 JavaScript에서는 자동으로 undefined를 반환한다. 이를 활용하여 함수의 결과를 확인할 수 있다.

2. 함수의 활용

2-1. 익명함수

익명 함수(Anonymous Function)는 이름이 없는 함수를 말한다. 이러한 함수는 변수에 할당하거나 다른 함수의 인자로 전달하거나 반환값으로 사용할 때 주로 활용된다. 익명 함수는 주로 함수 표현식을 통해 정의된다.

1) 함수를 변수에 할당하기

const add = function (a, b) {
  return a + b;
};

const result = add(2, 3);
console.log(result); // 출력: 5

2) 함수를 다른 함수의 인자로 사용하기

function operate(a, b, operation) {
  return operation(a, b);
}

const addition = function (x, y) {
  return x + y;
};

const subtraction = function (x, y) {
  return x - y;
};

console.log(operate(5, 3, addition)); // 출력: 8
console.log(operate(5, 3, subtraction)); // 출력: 2

3) 다른 함수를 함수의 반환값으로 사용하기

function createMultiplier(factor) {
  return function (x) {
    return x * factor;
  };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);

console.log(double(5)); // 출력: 10
console.log(triple(5)); // 출력: 15

2-2. Arrow 함수

Arrow Function은 ECMAScript 6 (ES6)에서 도입된 새로운 함수 표현식이다. 화살표 함수는 함수를 간결하게 작성할 수 있고, 주로 익명 함수로 사용된다.

// 기존의 함수 표현식
const add = function (a, b) {
  return a + b;
};

// Arrow Function
const addArrow = (a, b) => a + b;

console.log(add(2, 3)); // 출력: 5
console.log(addArrow(2, 3)); // 출력: 5

2-2-1. Arrow Function의 특징

1) 화살표 (=>)를 사용하여 함수를 정의한다.

2) 인자가 하나인 경우 소괄호 () 생략 가능하며, 인자가 없는 경우 빈 소괄호 ()를 사용한다.

3) 함수 몸체가 표현식인 경우 중괄호 {}를 생략하고 한 줄로 작성 가능한다.

4) 함수 몸체가 표현식인 경우 return 키워드를 생략할 수 있다.

Arrow Function은 주로 간단한 함수나 콜백 함수를 작성할 때 사용되며, 함수 내부의 this 값이 외부 스코프와 공유되는 특징을 가지고 있다. 이로 인해 함수 내에서 this를 사용할 때 혼동을 줄이고, 코드를 더 간결하게 작성할 수 있다.

2-3. IIFE

IIFE(Function)은 Immediately Invoked Function Expression의 줄임말로, 함수를 정의하고 즉시 호출하는 패턴을 나타낸다. IIFE는 주로 함수 스코프를 만들고 변수와 함수를 외부 스코프와 격리시키기 위해 사용된다.

2-3-1. IIFE의 주요 특징

1) IIFE는 함수를 정의한 후 즉시 호출하는 패턴이다.

2) 함수를 괄호 (function () {...})(); 안에 묶고 마지막에 다시 괄호 ()를 사용하여 호출한다.
3) IIFE 내에서 정의된 변수와 함수는 외부 스코프에서 접근할 수 없다.

4) IIFE 내부에서 정의한 변수는 외부 스코프와 격리되어 충돌을 방지하고 전역 스코프를 오염시키지 않는다.

(function hello() {
  console.log('IIFE');
})(); // 즉시 호출

(function () {
  var aName = "Kate";
  console.log(aName);
})(); // 내부 변수는 외부에서 접근 불가

const result = (function () {
  let name = "John";
  return name;
})(); // 결과만 저장

const total = ((x, y) => x + y); // 파라미터 사용
console.log(`total: ${total(1, 2)}`);

2-4. Closeure

클로저(Closure)는 함수가 정의될 때의 환경(스코프)에서 생성된 변수를 계속해서 기억하고 사용하는 현상을 나타낸다. 이는 함수 내부에서 함수를 반환하거나 다른 함수에 전달하여 외부 스코프에 있는 변수에 접근하고 변경할 수 있게 한다. 클로저는 다양한 상황에서 유용하게 활용된다.

1) 호출할 때마다 숫자를 증가시키는 함수

function createCounter() {
  let count = 0; // 지역 변수

  function increment() {
    count++;
    console.log(count);
  }

  return increment;
}

const counter1 = createCounter();
counter1(); // 출력: 1
counter1(); // 출력: 2

const counter2 = createCounter();
counter2(); // 출력: 1 (독립된 클로저)

createCounter 함수는 클로저를 반환합니다. 이 클로저는 count 변수를 기억하고 있으므로 호출할 때마다 숫자가 증가된다.

2) 분류 항목과 데이터를 저장하는 템플릿 형태의 함수

function createItemTemplate(category) {
  const items = [];

  return function addItem(item) {
    items.push({ category, item });
    console.log(items);
  };
}

const addFruit = createItemTemplate('Fruit');
addFruit('Apple'); // 출력: [{ category: 'Fruit', item: 'Apple' }]
addFruit('Banana'); // 출력: [{ category: 'Fruit', item: 'Apple' }, { category: 'Fruit', item: 'Banana' }]

const addVegetable = createItemTemplate('Vegetable');
addVegetable('Carrot'); // 출력: [{ category: 'Vegetable', item: 'Carrot' }]

createItemTemplate 함수는 특정 카테고리를 가지는 아이템을 저장하는 클로저를 반환한다. 각 클로저는 독립적인 아이템 목록을 유지하며, 분류 항목(category)을 기억한다.

클로저는 데이터 은닉, 정보 보호, 비동기 작업 처리 등 다양한 상황에서 활용된다.

 

728x90

'웹 서비스 개발(FB,BE,SERVER,DB) > Javascript' 카테고리의 다른 글

DOM API  (0) 2024.03.06
4. 비동기처리  (1) 2024.03.06
2. 자료형(DataType)  (1) 2024.03.06
1. JavaScript  (0) 2024.03.04

댓글