함수는 어떻게 사용할 수 있을까?
함수 선언
--
함수는
어떤 목적을 가지고 작성한 코드를 모아 둔 블록문으로
호이스팅이 되기 때문에 함수를 밑에 선언하더라도 위에서 해당 함수에 접근할 수 있다.
기본 형식 (네이밍 함수)
// 함수 선언하기
function 함수명 (입력값) {
// 수행할 일
return 반환값 // 반환할 값이 존재한다면 사용 (선택사항)
}
// 함수 호출하기
함수명(입력값);
return문은
메서드에서 수행한 값을 외부로 반환할 때 사용된다.
예시 코드
function add(x, y) {
return x + y;
}
let z = add(2, 3); // z = 2 + 3;
console.log(z); // 5
function gugudan() {
for(let i = 1; i <= 9; i++) {
console.log(`3 * ${i} = ${3 * i}`);
}
}
gugudan();
위 코드처럼 함수에 함수명(add, gugudan)을 정의한 함수를 "네이밍 함수"라고 부른다.
상수 또는 변수에 함수를 대입하여 사용할 수도 있다. (대신 호이스팅 불가능)
const ggd = function gugudan() {
for(let i = 1; i <= 9; i++) {
console.log(`3 * ${i} = ${3 * i}`);
}
};
ggd();
함수명을 정의하지 않고 함수를 정의할 수도 있다. (이를 "익명 함수"라고 부른다.)
const subt = function (x, y) {
return x - y;
}
console.log(subt(7, 2));
함수 표현식으로는 함수를 정의할 때 주로 "const"키워드로 사용한다.
물론 var, let 키워드를 사용해도 문제가 없지만
일반적으로 함수는 일관된 목적을 가진 코드 집합이기 때문에 "재정의" 또는 "재할당"하면 안 되는 경우가 있다.
--
화살표 함수
--
ES6에서 추가된 함수 정의 방법으로, 화살표를 사용해서 함수를 정의하는 방법이다.
기본 형식
() => {};
익명 함수처럼 함수명이 정의되어 있지 않아서
익명 함수처럼 해당 함수를 변수에 할당하는 방법으로 사용해야 한다.
예시 코드
const gugudan = () => {
for(let i = 1; i <= 9; i++) {
console.log(`3 * ${i} = ${3 * 1};
}
};
gugudan();
// 한 줄 안에 값만 반환시 중괄호 생략 가능
const mult = (x, y) => x * y;
console.log(mult(2, 7));
// 두 줄 이상의 작업이 있을 시 중괄호 생략 불가능
const mult = (x, y) => {
console.log(`${x}와 ${y}를 곱합니다.`);
console.log(`결과는 ${x * y}입니다.`);
return x * y;
};
console.log(mult(2, 7));
// 인자(매개변수)가 하나일 때는 괄호 없이 선언 가능
const pow = x => x ** 2;
console.log(pow(3));
--
매개변수 & 인수(인자)
--
// 함수 선언문
function 함수명(매개변수1, 매개변수2, ...) { }
// 함수 표현식
const 함수명 = function 식별자(매개변수1, 매개변수2, ...) { }
// 화살표 함수
const 함수명 = (매개변수1, 매개변수2, ...) => { };
// 함수 호출
함수명(인수1, 인수2, ...);
인수 데이터를 매개변수로 전달
function sum(num1, num2) { }
sum(10, 20);
매개변수로 데이터 전달 X
function sum(num1, num2) { }
sum();
오류가 발생하지 않고 데이터를 전달받지 못한 매개변수(num1, num2)는
undefined 값으로 초기화되어 메서드가 호출된다.
매개변수가 없는 경우 인수를 전달
function sum() { }
sum(10, 20);
오류가 발생하지 않고, 전달한 인수는 그냥 무시되어 메서드를 호출한다.
매개변수에 기본값 할당
function sum(a = 10, b = 20) {
console.log(a, b);
}
sum();
매개변수에 기본값이 할당 되어있을 경우
인수가 없다면 해당 기본값으로 사용하며, 인수가 전달되면 전달된 데이터로 변경하여 사용된다.
--
일급 객체
--
일급 객체는
함수를 변수와 같이 다루는 언어에 있는 개념으로 아래와 같은 특징이 있다.
- 상수 또는 변수에 함수를 할당 가능
- 함수를 다른 함수에 인자로 전달 가능
- 함수의 반환값에 함수를 사용 가능
즉, 함수를 변수처럼 사용할 수 있는 특징이 있다.
자바스크립트의 함수도 일급 객체다.
함수 할당
function isOddNum (number) {
console.log(
(number % 2 ? '홀' : '짝')
+ '수입니다.'
);
return number % 2 ? true : false;
};
// 함수를 변수에 할당하기
const checkIfOdd = isOddNum; // 뒤에 괄호 없음 유의
// checkIfOdd 변수는 이제 isOddNum 함수처럼 사용할 수 있다.
checkIfOdd(5);
객체에 함수 프로퍼티(속성)를 포함
// 객체 person
let person = {
name: '홍길동',
age: 30,
married: true,
introduce: function () {
return `저는 ${this.name}, ${this.age}살이고 `
+ `${this.married ? '기혼' : '미혼'}입니다.`;
}
}
console.log(person.introduce());
객체의 다른 프로퍼티(속성)에 접근하기 위해서는 "this를 사용한다.
this는 현제 위치(가까운 위치)의 객체를 의미하므로 this = person이 된다.
함수의 결과값으로 함수를 반환
function getIntroFunc (name, formal) {
return formal ? function () { console.log(`안녕하십니까, ${name}입니다.`);}
: function () {console.log(`안녕하세요~ ${name}이라고 해요.`);}
}
const hongIntro = getIntroFunc('홍길동', true);
const jeonIntro = getIntroFunc('전우치', false);
커링
필요한 인자보다 적은 수의 인자를 받으면
나머지 인자를 인자로 받는 다른 함수를 반환하는 방식이다.
// ⭐ 커링으로 작성된 함수
function curryAddMultSubt (a) {
return function (b) {
return function (c) {
return function (d) {
return (a + b) * c - d;
}
}
}
}
const curryAddMultSubt2 = a => b => c => d => (a + b) * c - d;
const curryAddMultSubtFrom2 = curryAddMultSubt(2);
const curryMultSubtFrom5 = curryAddMultSubt(2)(3);
const currySubtFrom20 = curryAddMultSubt(2)(3)(4);
--
다양한 함수 방식 종류
--
중첩 함수
함수를 중첩하여 작성할 수 있다.
function outer () {
const name = '바깥쪽'
console.log(name, '함수');
function inner () {
const name = '안쪽'
console.log(name, '함수');
}
inner();
}
outer();
재귀 함수
자기 자신(함수)를 재 호출할 수 있다.
다만 무한 루프에 빠지지 않도록 주의해야 한다.
(물론 무한 루프를 해야 하는 데몬인 경우 상관없다.)
function upto5 (x) {
console.log(x);
if (x < 5) {
upto5(x + 1);
} else {
console.log('- - -');
};
}
upto5(1);
upto5(3);
upto5(7);
즉시 실행 함수 (IIFE)
함수를 정의하는 동시에 실행까지 즉시 하는 함수다.
(요즘 잘 사용하지 않는다.)
기본 형식
(function (매개변수) {
// 함수 내용
})(인자);
- 소괄호로 해당 함수를 묶는다.
- 일회용 함수로 함수명이 존재하지 않는다.
예시 코드
(function sum(a, b) {
console.log(a + b);
})(10, 20);
const initialMessage = (function () {
var month = 8;
var day = 15;
var temps = [28, 27, 27, 30, 32, 32, 30, 28];
var avgTemp = 0;
for (const temp of temps) {
avgTemp += temp
}
avgTemp /= temps.length;
return `${month}월 ${day}일 평균기온은 섭씨 ${avgTemp}도입니다.`;
})();
console.log(initialMessage);
console.log(month);
--
스코프 (scope)
--
스코프는
변수나 함수와 같은 참조 대상 식별자를 찾아내기 위한 규칙으로
자바스크립트에서는 기본적으로 스코프에 따라 참조하려는 식별자를 찾는다.
"함수 스코프" 방식이냐 "블록 스코프"방식이냐에 따라
"전역 스코프"와 "지역 스코프"의 참조 범위가 달라진다.
함수 스코프
함수에서 정의한 블록문만 스코프의 유효 범위로 인정하는 방식으로
함수 내부는 "지역 스코프", 함수 외부는 "전역 스코프" 영역이 된다.
let a = 10; // 전역 스코프
function sum() {
console.log(`함수 내부: ${a}`);
}
sum();
console.log(`함수 외부: ${a}`);
-------------------------------------
함수 내부: 10
함수 외부: 10
function sum() {
let a = 10; // 지역 스코프
console.log(`함수 내부: ${a}`);
}
sum();
console.log(`함수 외부: ${a}`);
----------------------------------------
함수 내부: 10
ReferenceError: a is not defined
블록 스코프
let, const 키워드가 추가되면서 "블록 스코프"도 지원하게 된다.
블록{}을 기준으로 "전역 스코프"와 "지역 스코프"로 구분할 수 있다.
즉, 블록 스코프는 오직 let, const 키워드에서만 발생하므로
var 키워드에서는 참조 오류가 발생하지 않는다.
let a = 10;
{
let b = 20;
console.log(`코드 블록 내부 a: ${a}`);
console.log(`코드 블록 내부 b: ${b}`);
}
console.log(`코드 블록 내부 a: ${a}`);
console.log(`코드 블록 내부 b: ${b}`);
-----------------------------------------------
코드 블록 내부 a: 10
코드 블록 내부 b: 20
코드 블록 내부 a: 10
ReferenceError: a is not defined
var a = 10;
{
var b = 20;
console.log(`코드 블록 내부 a: ${a}`);
console.log(`코드 블록 내부 b: ${b}`);
}
console.log(`코드 블록 내부 a: ${a}`);
console.log(`코드 블록 내부 b: ${b}`);
--------------------------------------------
코드 블록 내부 a: 10
코드 블록 내부 b: 20
코드 블록 내부 a: 10
코드 블록 내부 b: 20
참조 우선순위
let, const 키워드는 같은 식별자(변수명)의 중복 선언이 불가능하다.
정확히는 같은 스코프 영역에서 중복 선언이 불가능한 것이다.
let a = 10;
const b = 20;
function sum() {
let a = 50;
console.log(`함수 내부 a: ${a}`);
console.log(`함수 내부 b: ${b}`);
}
sum();
-------------------------------
함수 내부 a: 50
함수 내부 b: 20
우선 같은 지역의 스코프의 식별자를 참조하고
만약 해당 식별자를 찾지 못하면 전역 스코프에서 찾아 참조한다.
--
함수 호이스팅
--
코드를 선언과 할당으로 분리하여 선언부를 자신의 스코프 최상위로 끌어올리는 것이다.
예시코드
console.log(num);
var num = 10;
위 코드처럼 작성하면 호이스팅으로 인해 아래 코드처럼 동작한다.
var num;
console.log(num); // undefined 출력
num = 10;
선언과 할당을 분리하여 선언을 먼저 하도록 하여 해당 변수의 존재를 알 수 있도록 한다.
단, 호이스팅은 var 키워드로 선언한 변수, 함수에만 적용된다.
함수 호이스팅 예시 코드
printHello();
function printHello() {
console.log("Hello");
}
위 코드처럼 작성하면 호이스팅으로 인해 아래 코드처럼 동작한다.
function printHello() { // 함수 선언문을 최상위로 올린다.
console.log("Hello");
}
printHello();
하지만 함수를 변수에 할당하는 방식(함수 표현식)에서는 예상과 다르게 동작한다.
printHello();
var printHello = function printHello(){
console.log("Hello");
}
위 코드처럼 작성하면 호이스팅으로 인해 아래 코드처럼 동작한다.
var printHello;
printHello();
printHello = function printHello() {
console.log("Hello");
}
-----------------------------------------
TypeError: printHello is not a function
--
'Language > Java Script' 카테고리의 다른 글
클래스 (+ 상속) (0) | 2025.03.27 |
---|---|
객체 기초 (0) | 2025.03.26 |
반복문 (0) | 2025.03.21 |
조건문 (0) | 2025.03.21 |
연산자 (0) | 2025.03.20 |