[Section 01] JavaScript 기초
< 06. 함수 >
- 함수는 재활용성이 좋아서 한 번만 정의해주면 어떤 애플리케이션에서든 호출해서 쓸 수 있다.
연습문제
1 ~ 9까지 구구단을 출력하는 코드를 for문으로 작성해주시오.
1. 문법
1.1. 함수 선언문
< 함수의 기본 형태 >
function gugudan() {
}
ex) 구구단 출력
function gugudan(){
for (i = 1; i <= 9; i++) {
console.log(`${i}단:`);
for (let j = 1; j <= 9; j++) {
console.log(`${i} * ${j} = ${i * j}`);
}
console.log("--");
}
}
gugudan();
1.2. 함수 표현식
< 함수의 기본 형태 >
const gugudan = function gugudan() {
}
ex) 구구단 출력
const a = function b(){
for (i = 1; i <= 9; i++) {
console.log(`${i}단:`);
for (let j = 1; j <= 9; j++) {
console.log(`${i} * ${j} = ${i * j}`);
}
console.log("--");
}
}
a();
- b();는 출력되지 않음, a라는 공간만 출력 가능하고, 함수를 파악 못함
: 변수 선언 키워드를 이용해 변수라는 공간을 만들어 줘야함
- let, const 중에 어떤 것을 사용해야 할까?
: 문법적으로는 상관없다, 관용적으로는 const 사용
: 함수는 개발과정에서 재할당하는 경우가 없기 때문
1.2.1. 네이밍 함수 (naming function)
- 변수에다가 함수의 이름을 넣어 주는 것 ( 함수 이름 o )
- 과거에 오류를 쉽게 파악하기 위해 많이 사용했음 (디버깅 쉽게 하기 위해)
const a = function b( ) { };
1.2.2. 익명 함수 (anonymous function)
- 함수 이름 없이 함수를 변수에 할당하는 것 ( 함수 이름 x )
const a = function ( ) { };
1.3. 화살표 함수 (함수 표현식에 포함됨)
const gugudan = function() {};
const gugudan = () => {};
ex)
const printHell = () => {
console.log("Hello");
};
printHell();
2. 호출 (call)
function gugudan() {
}
gugudan();
3. 매개변수 (parameter)
- 함수를 호출할 때 사용자가 원하는 값을 함수로 전달할 수 있게 함
ex) 구구단 중 특정 단수만 출력할 수 있게 한다면?
**
function gugudan(dan) {
for (let i = 1; i <= 9; i++){
console.log(`${dan} * ${i} = ${dan * i}`)
}
}
gugudan(2);
**
const gugudan = function (dan) {
for (let i = 1; i <= 9; i++){
console.log(`${dan} * ${i} = ${dan * i}`)
}
}
gugudan(2);
**
const gugudan = (dan) => {
for (let i = 1; i <= 9; i++){
console.log(`${dan} * ${i} = ${dan * i}`)
}
}
gugudan(2);
**
- 매개 변수 여러 값 전달 가능
- 전달은 가능하지만 꼭 다 받지는 않아도 된다.
- 매개변수가 인자보다 많다면 빈 공간이 되므로 undefined 출력됨.
- (dan, start, end = 10) 형식으로 기본값 설정 가능,
하지만 end 위치에 인자값을 전달하면 전달한 인자값이 기본값보다 우선
function gugudan(dan, start) {
for (let i = start; i <= 9; i++){
console.log(`${dan} * ${i} = ${dan * i}`)
}
}
gugudan(2, 3);
4. 반환 (return)
- 값을 함수 바깥으로 내보내줌
const sum = (n1, n2) => {
const result = n1 + n2;
console.log(result);
return result;
};
const result = sum(10, 20);
console.log(result);
const sum (n1, n2) => n1 + n2;
const result = sum(10, 20);
console.log(result);
- 주의 !!) 객체를 반환할 때
const obj = { name: "철수"};
const getValue = () => { name: "철수"};
console.log(getValue());
const obj = { name: "철수"};
const getValue = () => ({ name: "철수"});
console.log(getValue());
- 반환은 함수를 중단시키는 역할도 함
function gugudan(dan){
// 3단은 출력하면 안될 때
if (dan === 3){
console.log("3단 출력 안 됨")
return;
// 한 번 실행하고 함수를 멈춰버림
// 의미 없는 undefined 값을 내보내면서 함수를 종료시키는 것
}
for (let i =1; i <= 9; i++){
console.log(`${dan} * ${i} = ${dan * i}`);
}
}
gugudan(3);
5. 가변인자
- 인자의 여러가지 경우의 수를 가능하게 해줌
- 재사용성이 조금 아쉬움
const sum = (n1, n2, n3) => n1 + n2 + n3;
console.log(sum(10,20,30));
undefined가 되면서 NaN이 되는 문제점
5.1. arguments
- 매개변수가 몇 개 넘어왔는지 보여주는 것
- 유사배열객체의 일종
배열(array) [ ]
안에 중괄호 { }
없이는 키
와 값
이 들어갈 수 없다.
- 주의!! 화살표 함수는 arguments라는 속성을 자체적으로 가지지 않는다.
(화살표 함수에서는 사용 불가)
5.2 스프레드 연산자 (전개 연산자, 나머지 연산자)
const sum = (...args) => {
let sum = 0;
for (let value of args){
sum += value;
}
return sum;
};
console.log(sum(10, 20));
console.log(sum(10, 20, 30));
console.log(sum(10, 20, 30, 40));
6. 스코프
6.1. 함수 스코프
const a = 10;
function print(){
const b = 20;
console.log(`함수 내부: ${a}, ${b}`);
}
print();
console.log(`함수 외부: ${a}, ${b}`);
6.2. 블록 스코프
- 지역 스코프
{ }
사이에 작성된 block 영역
- 주의 !)
let
과 const
만 블록 스코프 가능, var
불가능
const a = 10;
{
const b = 20;
console.log(`블록 내부: ${a}, ${b}`);
{
const c = 30;
console.log(`블록 내부의 내부: ${a}, ${b}, ${c}`);
}
}
console.log(`블록 외부: ${a}, ${b}, ${c}`);
6.3 전역 스코프
- 지역에서 전역 참조는 가능, 전역에서 지역 참조 불가
연습문제
Q1. 총 합 덧셈 함수
매개변수를 전달받아서 매개변수의 총 합을 반환하는 덧셈 함수를 만들어주세요.
매개변수의 갯수 제한은 없습니다.
- < 문제 풀이 >
function sum() {
let sum = 0;
for (let value of arguments) {
sum += value;
}
return sum;
}
console.log(sum(10, 20));
const sum = (...args) => {
let sum = 0;
for (let number of args) {
sum += number;
}
return sum;
};
const results1 = sum(10, 20, 30);
console.log(results1);
Q2. 사칙연산
사칙연산을 수행하는 로직을 담은 함수를 구현해주세요.
(매개변수 - 2개) (+, -, *, /)
구현 방법은 자율입니다.
- < 문제 풀이 >
const calculate = (n1, n2, operator) => {
switch (operator) {
case "+":
return n1 + n2;
case "-":
return n1 - n2;
case "*":
return n1 * n2;
case "/":
return n1 / n2;
default:
return "지원하지 않는 연산 기호입니다.";
}
};
console.log(calculate(10, 10, "/"));
Q3. 짝수 홀수 판별
숫자를 매개변수로 받아서 짝수면 true, 홀수면 false를 반환하는
함수 isEven을 작성하세요.
함수를 사용하여 7이 짝수인지 홀수인지 판별하고 결과를 출력하세요.
Q4. 배열의 모든 요소 더하기
배열의 모든 요소의 합을 반환하는 함수를 작성하세요
console.log(sumArray([1, 2, 3]));
Q5. 배열의 최대값 찾기
배열에서 최대값을 찾는 함수를 작성하세요
console.log(findMax([1, 5, 3, 9, 2]));
- < 문제 풀이 >
const findMax = (numberArr) => {
let max = numberArr[0];
for (let number of numberArr) {
if (number > max) {
max = number;
}
}
return max;
};
console.log(findMax([1, 5, 3, 9, 2]));
Q6. 문자열 반전
주어진 문자열을 반전시켜 반환하는 함수를 작성하세요
console.log(reverseString("hello"));
Q7. 문자열에서 특정 문자 개수 세기
주어진 문자열에서 특정 문자의 개수를 세는 함수를 작성하세요
console.log(countCharacter("banana", "a"));
- < 문제 풀이 >
const word = "banana";
const countCharacter = (w) => {
let count = 0;
for (let i = 0; i < word.length; i++) {
if (word[i] === w) {
count++;
}
}
return count;
};
console.log(countCharacter("a"));
const countCharacter = (str, char) => {
let count = 0;
for (let i = 0; i < str.length; i++) {
if (str[i] === char) count += 1;
}
return count;
};
console.log(countCharacter("banana", "a"));
Q8. 팩토리얼 계산하기
양의 정수를 매개변수로 받아서
그 수의 팩토리얼을 반환하는 함수 `factorial`을 작성하세요.
함수를 사용하여 5의 팩토리얼을 계산하고 결과를 출력하세요.
Q9. 삼각형 넓이 계산하기
삼각형의 밑변과 높이를 매개변수로 받아서
넓이를 반환하는 함수 triangleArea를 작성하세요.
함수를 사용하여 밑변이 10이고 높이가 5인 삼각형의 넓이를 계산하고
결과를 출력하세요.
- < 문제 풀이 >
const triangleArea = (width, height) => {
return width * height * 0.5;
};
console.log(triangleArea(10, 5));
const triangleArea = (width, height) => width * height * 0.5;
console.log(triangleArea(10, 5));
연습문제 +
Q1. 특정문자 제거
주어진 문자열에서 특정 문자를 제거하는 함수를 작성하시오.
removeChar("hello world", "o");
- < 문제 풀이 >
function removeChar(str, char) {
let result = "";
for (let value of str) {
if (value !== char) result += value;
}
return result;
}
console.log(removeChar("hello world", "o"));
function removeChar(str, char) {
let result = "";
for (let i = 0; i < str.length; i++) {
if (str[i] !== char) result += str[i];
}
return result;
}
console.log(removeChar("hello world", "o"));
Q2. 배열요소 반
주어진 배열의 요소를 반전 시키는 함수를 작성하시오.
reverseArray([1, 2, 3, 4, 5]);
- < 문제 풀이 >
function reverseArray(array) {
const temp = [];
for (let i = array.length - 1; i >= 0; i--) {
temp.push(array[i]);
}
return temp;
}
console.log(reverseArray([1, 2, 3, 4, 5]));
Q3. 특정 숫자 찾기
주어진 배열에서 특정 숫자가 있는지 확인하는 함수를 작성하시오.
containsNumber([1, 2, 3, 4, 5], 5);
containsNumber([1, 2, 3, 4, 5], 7);
- < 문제 풀이 >
function containsNumber(array, number) {
let res = "없음";
for (let i = 0; i < array.length; i++) {
if (array[i] === number) res = "있음";
}
console.log(res);
return res;
}
containsNumber([1, 2, 3, 4, 5], 5);
containsNumber([1, 2, 3, 4, 5], 7);
function containsNumber(numArr, num) {
for (let n of numArr) {
if (n === num) return true;
}
return false;
}
console.log(containsNumber([1, 2, 3, 4, 5], 5));
console.log(containsNumber([1, 2, 3, 4, 5], 7));
function containsNumber(array, number) {
let res = "없음";
for (let i = 0; i < array.length; i++) {
if (array[i] === number) res = "있음";
break;
}
return res;
}
console.log(containsNumber([1, 2, 3, 4, 5], 5));
console.log(containsNumber([1, 2, 3, 4, 5], 7));
Q4. 애너그램인지 확인
두 문자열이 애너그램(서로 다른 순서로 같은 문자를 가지는 경우)인지
확인하는 함수를 작성하시오. (알파뱃)
isAnagrams("listen", "silent");
isAnagrams("fluster", "restful");
isAnagrams("rat", "car");
isAnagrams("aaa", "aaaa");
- < 문제 풀이 >
function isAnagrams(char1, char2) {
let res = "다름";
for (let i = 0; i < char1.length; i++) {
for (let j = 0; j < char2.length; j++) {
if (char1[i] === char2[j]) res = "같음";
break;
}
if (char1.length !== char2.length) res = "다름";
}
console.log(res);
return res;
}
isAnagrams("listen", "silent");
isAnagrams("fluster", "restful");
isAnagrams("rat", "car");
isAnagrams("aaa", "aaaa");
function isAnagrams(str1, str2) {
if (str1.length !== str2.length) return false;
const charCount = {};
for (let char of str1) {
charCount[char] = (charCount[char] || 0) + 1;
}
for (let char2 of str2) {
if (!charCount[char2]) return false;
charCount[char2]--;
}
return true;
}
console.log(isAnagrams("listen", "silent"));
const isAnagrams = (word1, word2) => {
if (word1.length !== word2.length) return false;
const object = {};
for (const letter of word1) {
object[letter] = object[letter] + 1 || 1;
}
for (const letter of word2) {
if (!object[letter]) {
return false;
}
object[letter]--;
}
return true;
};
console.log('4번 답');
console.log(isAnagrams('listen', 'silent'));
console.log(isAnagrams('fluster', 'restful'));
console.log(isAnagrams('rat', 'car'));
Q5. 배열에서 두 수의 합
주어진 배열에서 두 수의 합이 특정 목표값이 되는 쌍을 찾아
반환하는 함수를 작성하시오.
twiceSum([1, 2, 3, 4, 5], 5);
twiceSum([1, 2, 3, 4, 5], 9);
twiceSum([1, 2, 3, 4, 5], 6);
- < 문제 풀이 >
function twiceSum(array, n) {
const temp = [];
for (let i = 0; i < array.length; i++) {
for (let j = i + 1; j < array.length; j++) {
if (array[i] + array[j] === n) temp.push(`${array[i]}, ${array[j]}`);
}
}
console.log(temp);
return temp;
}
twiceSum([1, 2, 3, 4, 5], 5);
twiceSum([1, 2, 3, 4, 5], 9);
twiceSum([1, 2, 3, 4, 5], 6);
function twiceSum(numArr, num) {
const result = [];
for (let i = 0; i < numArr.length; i++) {
for (let j = i + 1; j < numArr.length; j++) {
if (numArr[i] + numArr[j] === num) result.push([numArr[i], numArr[j]]);
}
}
return result;
}
console.log(twiceSum([1, 2, 3, 4, 5], 5));
console.log(twiceSum([1, 2, 3, 4, 5], 9));
console.log(twiceSum([1, 2, 3, 4, 5], 6));
연습문제 ++
Q1. 문자열 압축
문자열이 주어졌을 때, 연속된 동일한 문자를 하나의 문자와
그 문자의 개수로 압축해서 반환하는 함수를 만들어주세요.
const i = "aaabbbccc";
const o = "a3b3c3";
const i2 = "aabbaa";
const o2 = "a2b2a2";
const i3 = "abbbffd";
const o3 = "a1b3f2d1";
const i4 = "aabaa";
const o4 = "a2b1a2";
Q2. 팰린드롬 확인하기 (쉬운 버전)
주어진 문자열이 팰린드롬인지 확인하는 함수를 작성하세요.
팰린드롬이란 앞에서부터 읽으나 뒤에서부터 읽으나 같은 문자열을 말합니다.
대소문자를 구분하지 않으며,
매개변수는 항상 공백 없이 소문자 알파뱃만 넘어온다고 가정합니다.
console.log(isPalindrome("racecar"));
console.log(isPalindrome("hello"));
console.log(isPalindrome("level"));
console.log(isPalindrome("world"));
Q3. 펠린드롬 확인하기 (어려운 버전)
주어진 문자열이 팰린드롬인지 확인하는 함수를 작성하세요.
팰린드롬이란 앞에서부터 읽으나 뒤에서부터 읽으나 같은 문자열을 말합니다.
대소문자를 구분하지 않으며, 알파벳 이외의 문자는 무시합니다.
console.log(isPalindromeSentence("A man, a plan, a canal, Panama!"));
console.log(isPalindromeSentence("Was it a car or a cat I saw?"));
console.log(isPalindromeSentence("Hello, world!"));
console.log(isPalindromeSentence("No 'x' in Nixon"));
- < 문제 풀이 >
- 문자열에서 알파벳만 추출하는 것이 핵심
- 정규식을 사용해야 함. 하지만 우린 안 배운다
정규식이라는 것이 양이 방대하기 때문
- AI를 개발 생산성이 높아지는 범위 안에서는
적극적으로 사용해야 한다고 생각하심 (챗 GPT 사용 권장)
function isPalindromeSentence(str) {
const cleanedStr = str.toLowerCase().replace(/[^a-z]/g, "");
const reversed = cleanedStr.split("").reverse().join("");
return cleanedStr === reversed;
}
console.log(isPalindromeSentence("A man, a plan, a canal, Panama!"));
console.log(isPalindromeSentence("Was it a car or a cat I saw?"));
console.log(isPalindromeSentence("Hello, world!"));
console.log(isPalindromeSentence("No 'x' in Nixon"));
Q4. 최대 공약수(GCD)
두 정수를 전달 받아서 최대 공약수를 구하는 함수를 구현하세요.
최대 공약수는 공통된 약수 중 가장 큰 수를 의미합니다.
예) 12 - 1, 2, 3, 4, 6 12
18 - 1, 2, 3, 6, 9, 18
약수 : 1, 2, 3, 6
최대 공약수 6
gcd(56, 98);
gcd(101, 10);
gcd(15, 5);
gcd(100, 75);
gcd(18, 24);
- < 문제 풀이 >
function gcd(a, b) {
if (b === 0) return a;
return gcd(b, a % b);
}
console.log(gcd(56, 98));
console.log(gcd(101, 10));
console.log(gcd(15, 5));
console.log(gcd(100, 75));
console.log(gcd(18, 24));
- 두 수를 나누어 떨어지게 하는 최대한 작은 수
function gcd(a, b) {
if (b === 0) return a;
return gcd(b, a % b);
}
console.log(gcd(100, 24));
function lcm(a, b) {
return (a * b) / gcd(a, b);
}
console.log(lcm(100, 24));
Q5. 배열 정렬(버블 정렬)
주어진 배열을 오름차순으로 정렬하는 함수를 작성하시오.
console.log(bubbleSort([5, 3, 8, 1, 2]));
- < 문제 풀이 >
- 버블 정렬은 정렬이 끝나도 끝까지 해야 끝나기 때문에
효율성이 떨어지는 정렬 방법임
- 배열의 앞 뒤 바꾸는 것
const arr = [1, 2, 3];
const temp = [0];
arr[0] = arr[1];
arr[1] = temp;
console.log(arr);
function bubbleSort(array) {
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
const temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
console.log(bubbleSort([5, 3, 8, 1, 2]));
연습문제 (최대 공약수, 최소 공배수)
Q1. 최대 공약수과 최소 공배수
두 수를 입력받아 두 수의 최대공약수와 최소공배수를 반환하는 함수,
solution을 완성해 보세요.
배열의 맨 앞에 최대공약수, 그다음 최소공배수를 넣어 반환하면 됩니다.
예를 들어 두 수 3, 12의 최대공약수는 3, 최소공배수는 12이므로
solution(3, 12)는 [3, 12]를 반환해야 합니다.
[제한사항]
두 수는 1이상 1000000이하의 자연수입니다.
[입출력]
console.log(solution(3, 12));
console.log(solution(2, 5));
- < 문제 풀이 >
function solution(a, b) {
const temp = [];
function gcd(a, b) {
if (b === 0) return a;
return gcd(b, a % b);
}
temp.push(a);
function lcm(a, b) {
return lcm((a * b) / gcd(a, b));
}
temp.push((a * b) / gcd(a, b));
console.log(temp);
return temp;
}
solution(2, 5);
console.log(solution(3, 12));
console.log(solution(2, 5));
function gcd(a, b) {
if (b === 0) return a;
return gcd(b, a % b);
}
function solution(a, b) {
return [gcd(a, b), (a * b) / gcd(a, b)];
}
console.log(solution(3, 12));
console.log(solution(2, 5));
Q2. N개의 최소공배수
두 수의 최소공배수(Least Common Multiple)란
입력된 두 수의 배수 중 공통이 되는 가장 작은 숫자를 의미합니다.
예를 들어 2와 7의 최소공배수는 14가 됩니다.
정의를 확장해서,
n개의 수의 최소공배수는 n 개의 수들의 배수 중
공통이 되는 가장 작은 숫자가 됩니다.
n개의 숫자를 담은 배열 arr이 입력되었을 때
이 수들의 최소공배수를 반환하는 함수, solution을 완성해 주세요.
[제한사항]
- arr은 길이 1이상, 15이하인 배열입니다.
- arr의 원소는 100 이하인 자연수입니다.
[입출력]
console.log(solution([2,6,8,14]));
console.log(solution([1,2,3]));
console.log(solution([3, 5, 15]));
- < 문제 풀이 >
function gcd(a, b) {
if (b === 0) return a;
return gcd(b, a % b);
}
function solution(numArr) {
let result = numArr[0];
for (let i = 0; i < numArr.length - 1; i++) {
const lcm = (numArr[i] * numArr[i + 1]) / gcd(numArr[i], numArr[i + 1]);
result = (result * numArr[i + 1]) / gcd(result, numArr[i + 1]);
}
return result;
}
console.log(solution([2, 6, 8, 14]));
console.log(solution([1, 2, 3]));
console.log(solution([3, 5, 15]));