본문 바로가기

멋쟁이사자처럼_부트캠프/JavaScript

[멋쟁이사자처럼 부트캠프 TIL 회고] 백엔드 부트캠프 13기: Java 25일차 JavaScript 함수

JavaScript에서 함수

함수(Function)는 특정 작업을 수행하도록 설계된 자바스크립트 코드 블록입니다. 함수는 재사용 가능한 코드 단위로, 입력(매개변수)을 받아 처리를 수행한 뒤, 결과값(반환값)을 반환하거나, 특정 작업을 실행합니다.

함수의 주요 특징

  1. 재사용성: 한 번 정의하면 여러 번 호출 가능.
  2. 모듈화: 코드를 분리하여 가독성과 유지보수성 향상.
  3. 일급 객체: 자바스크립트에서 함수는 일급 객체로 취급됩니다.
    • 변수에 할당할 수 있음.
    • 다른 함수의 매개변수로 전달 가능.
    • 함수의 반환값으로 사용 가능.

 

함수 정의 방법

 

1. 함수 선언문 (Function Declaration)

가장 기본적인 함수 정의 방법입니다.

function greet(name) {
  return `Hello, ${name}!`;
}

console.log(greet("Alice")); // Hello, Alice!

 

2. 함수 표현식 (Function Expression)

함수를 변수에 할당하여 정의합니다.

const greet = function (name) {
  return `Hello, ${name}!`;
};

console.log(greet("Bob")); // Hello, Bob!

3. 화살표 함수 (Arrow Function)

ES6에서 도입된 간결한 함수 표현식입니다.

const greet = (name) => `Hello, ${name}!`;

console.log(greet("Charlie")); // Hello, Charlie!

 

화살표 함수

화살표 함수와 일반 function 으로 만든 함수와의 주요 차이점은 화살표 함수에서 가르키는 this 와 function 에서 가르키는 this 가 서로 다르다는거다.

 

화살표 함수 주의점

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      const dog = {
        name: "멍멍이",
        sound: "멍멍!!",
        say: function () {
          console.log(this.sound);
          console.log("dog 객체안에서의 ::  " + this);
        },
        //화살표 함수의 this 는 브라우저에서 Window 객체이다.  때문에
        // 객체안에서 함수를 정의할 때에는 화살표함수를 사용하면 안된다!!!!  (중요!!)
        say2: () => {
          console.log("화살표 함수:::" + this);
          console.log(this.sound);
        },
      };

      dog.say();
      dog.say2();

      function test() {
        console.log(this);
      }

      test();
    </script>
  </body>
</html>

 

4. 즉시 실행 함수 (IIFE: Immediately Invoked Function Expression)

정의와 동시에 실행되는 함수입니다.

(function () {
  console.log("This is an IIFE!");
})();

함수의 구성 요소

  1. 매개변수 (Parameters): 함수가 입력으로 받을 변수.
  2. 반환값 (Return Value): 함수 실행 결과로 반환되는 값.
  3. 함수 몸체 (Body): 함수가 실행될 때 수행하는 코드.
function add(a, b) {
  return a + b; // 반환값
}

console.log(add(3, 4)); // 7

기본 매개변수 (Default Parameters)

매개변수의 기본값을 설정할 수 있습니다.

function greet(name = "Guest") {
  return `Hello, ${name}!`;
}

console.log(greet()); // Hello, Guest!
console.log(greet("Alice")); // Hello, Alice!

 

익명 함수 (Anonymous Function)

이름이 없는 함수입니다. 함수 표현식이나 콜백 함수로 자주 사용됩니다.

setTimeout(function () {
  console.log("This runs after 1 second.");
}, 1000);

 

함수의 반환값

  • return 키워드를 사용하여 값을 반환합니다. 반환값이 없는 경우 undefined를 반환합니다.
function square(x) {
  return x * x;
}

console.log(square(5)); // 25

 

콜백 함수 (Callback Function)

다른 함수의 매개변수로 전달되는 함수.

function processUserInput(callback) {
  const name = "Alice";
  callback(name);
}

processUserInput(function (name) {
  console.log(`Hello, ${name}!`);
});

 

JavaScript의 특별한 함수 특성

1. 가변 인자 (Rest Parameters)
여러 개의 인자를 배열로 받을 수 있습니다.

function sum(...numbers) {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}

console.log(sum(1, 2, 3, 4)); // 10

 

2. arguments 객체
함수 호출 시 전달된 모든 인자를 배열 형태로 저장.

function showArguments() {
  console.log(arguments);
}

showArguments(1, 2, 3); // [1, 2, 3]

 

3. 클로저 (Closure)
내부 함수가 외부 함수의 변수를 기억하는 특성.

function outer() {
  let count = 0;
  return function inner() {
    count++;
    return count;
  };
}

const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2

호이스팅(Hoisting)

자바스크립트에서 변수와 함수 선언이 코드 실행 이전에 최상단으로 끌어올려지는 동작을 말합니다. 즉, 변수와 함수의 선언부가 해당 스코프의 최상단으로 옮겨지는 것처럼 동작합니다.

호이스팅의 원리

  1. 변수 선언함수 선언만 호이스팅됩니다.
    • 선언만 끌어올려지고, 값 할당은 끌어올려지지 않습니다.
    • 초기화나 실행은 해당 코드가 도달했을 때 수행됩니다.
  2. var, let, const, 그리고 함수 선언이 모두 호이스팅됩니다. 하지만 동작 방식은 다릅니다.

 

호이스팅 예제

1. 변수 호이스팅 (var 키워드)

console.log(myVar); // undefined
var myVar = 5;
console.log(myVar); // 5
  • var로 선언된 변수는 선언만 끌어올려지기 때문에, 초기화 전에 접근하면 undefined가 출력됩니다.
  • 실제 동작 방식:
var myVar;
console.log(myVar); // undefined
myVar = 5;
console.log(myVar); // 5

2. let/const 호이스팅

console.log(myVar); // ReferenceError: Cannot access 'myVar' before initialization
let myVar = 5;
  • let과 const로 선언된 변수도 호이스팅되지만, Temporal Dead Zone(TDZ)라는 개념 때문에 초기화 전에 접근하면 오류가 발생합니다.

3. 함수 선언문

sayHello();

function sayHello() {
  console.log("Hello!");
}
  • 함수 선언문은 완전히 끌어올려지기 때문에, 호출을 선언부보다 앞에 작성해도 정상적으로 실행됩니다.
  • 실제 동작 방식:
function sayHello() {
  console.log("Hello!");
}
sayHello();

4. 함수 표현식

sayHello(); // TypeError: sayHello is not a function

var sayHello = function () {
  console.log("Hello!");
};
  • 함수 표현식은 변수에 함수가 할당되는 방식이므로, 변수의 선언만 호이스팅되고 함수는 초기화 전에 접근하면 오류가 발생합니다.
  • 실제 동작 방식:
var sayHello;
sayHello(); // TypeError
sayHello = function () {
  console.log("Hello!");
};

 

 

호이스팅의 주요 포인트

  1. 선언만 끌어올려지고, 초기화는 끌어올려지지 않습니다.
  2. let과 const는 TDZ를 가지고 있어 초기화 전에 접근이 불가능합니다.
  3. 함수 선언문은 완전히 끌어올려져 초기화와 함께 사용할 수 있습니다.
  4. 함수 표현식은 var처럼 동작하므로 초기화 전 접근이 불가능합니다.

호이스팅의 실전 교훈

  • 변수를 선언하기 전에 사용하지 말 것!
  • 코드를 더 읽기 쉽게 작성하기 위해 항상 변수와 함수 선언을 코드 상단에 작성하세요.

 


JavaScript에서 객체

const dog = {
    name: '멍멍이',
    age: 2
};
console.log(dog.name);
console.log(dog.age);

//결과
멍멍이
2

객체를 선언 할 때에는 이렇게 { } 문자 안에 원하는 값들을 넣어주면 된다.

값을 집 어 넣을 때에는

키: 원하는 값

형태로 넣으며, 키에 해당하는 부분은 공백이 없어야한다.

만약에 공백이 있어야 하는 상황이라면 이를 따옴표로 감싸서 문자열로 넣어주면 된다.

const sample = {
	'key with space': true
};

 

 

함수에서 객체를 파라미터로 받기

const ironMan = {
  name: "토니 스타크",
  actor: "로버트 다우니 주니어",
  alias: "아이언맨",
};
const captainAmerica = {
  name: "스티븐 로저스",
  actor: "크리스 에반스",
  alias: "캡틴 아메리카",
};
function print(hero) {
  const text = `${hero.alias}(${hero.name}) 역할을 맡은 배우는 ${hero.actor} 입니다.`;
  console.log(text);
}
print(ironMan);
print(captainAmerica);

 

결과 :

아이언맨(토니 스타크) 역할을 맡은 배우는 로버트 다우니 주니어 입니다.
캡틴 아메리카(스티븐 로저스) 역할을 맡은 배우는 크리스 에반스 입니다.

 

아래 코드는 객체에서 값들을 추출해서 새로운 상수로 선언해 준다. 여기서 더 나아가면, 파라미터 단계에서 객체 비구조화 할당을 할 수도 있다.

const { alias, name, actor } = hero;
const ironMan = {
name: '토니 스타크',
actor: '로버트 다우니 주니어',
alias: '아이언맨'
};
const captainAmerica = {
name: '스티븐 로저스',
actor: '크리스 에반스',
alias: '캡틴 아메리카'
};
function print({ alias, name, actor }) {
const text = `${alias}(${name}) 역할을 맡은 배우는 ${actor} 입니다.`;
console.log(text);
}
print(ironMan);
print(captainAmerica);

 

JavaScript에서 getter와 setter를 사용하는 예제

 

Getter 함수와 Setter 함수를 사용하게 되면 특정 값을 바꾸려고 하거나, 특정 값을 조회하려고 할 때 우리가 원하는 코드를 실행 시킬 수 있다.

 

const numbers = {
  _a: 1,
  _b: 2,
  sum: 3,
  calculate() {
    console.log("calculate");
    this.sum = this._a + this._b;
  },
  get a() {
    return this._a;
  },
  get b() {
    return this._b;
  },
  set a(value) {
    console.log("a가 바뀝니다.");
    this._a = value;
    this.calculate();
  },
  set b(value) {
    console.log("b가 바뀝니다.");
    this._b = value;
    this.calculate();
  },
};
console.log(numbers.sum);
numbers.a = 5;
numbers.b = 7;
numbers.a = 9;
console.log(numbers.sum);
console.log(numbers.sum);
console.log(numbers.sum);
3
a가 바뀝니다.
calculate
b가 바뀝니다.
calculate
a가 바뀝니다.
calculate
3
16
16
16

 

Setter 함수를 설정 할 때에는 함수의 앞부분에 set 키워드를 붙인다. Setter 함수를 설정하고 나면, numbers.a = 5 이렇게 값을 설정했을 때 5 를 함수의 파라미터로 받아오게 된다.

위 코드에서는 객체 안에 _a, _b 라는 숫자를 선언해주 고, 이 값들을 위한 Getter 와 Setter 함수를 설정해주었다. 아까 전에는 만든 객체에서는 numbers.sum 이 조회 될 때마다 덧셈이 이루어졌었 지만, 이제는 a 혹은 b 값이 바뀔 때마다 sum 값을 연산한다.

 


배열

생성

// 빈 배열 생성
let emptyArray = [];

// 요소를 포함하는 배열 생성
let numbers = [1, 2, 3, 4, 5];
let mixedArray = [1, "hello", true, null];

 

//요소에 접근
let fruits = ["apple", "banana", "cherry"];
console.log(fruits[0]); // apple (첫 번째 요소)
console.log(fruits[fruits.length - 1]); // cherry (마지막 요소)

//배열 끝에 추가: push() 메서드
fruits.push("orange"); // ["apple", "banana", "cherry", "orange"]

//배열 앞에 추가: unshift() 메서드
fruits.unshift("grape"); // ["grape", "apple", "banana", "cherry", "orange"]

//특정 위치에 추가: splice() 메서드
fruits.splice(2, 0, "kiwi"); // ["grape", "apple", "kiwi", "banana", "cherry", "orange"]

//배열 끝에서 삭제: pop() 메서드
fruits.pop(); // ["grape", "apple", "kiwi", "banana", "cherry"]

//배열 앞에서 삭제: shift() 메서드
fruits.shift(); // ["apple", "kiwi", "banana", "cherry"]

//특정 위치에서 삭제: splice() 메서드
fruits.splice(1, 1); // ["apple", "banana", "cherry"]

//배열 요소 수정하기
fruits[1] = "pear"; // ["apple", "pear", "cherry"]

//배열의 길이
console.log(fruits.length); // 3

 

while문

let i = 0;
while (i < 10) {
  console.log(i);
  i++;
}

 

for...of문

let numbers = [10, 20, 30, 40, 50];
for (let number of numbers) {
  console.log(number);
}

 

for...in문 : 객체의 정보를 배열 형태로 받아올 수 있는 함수

const doggy = {
  name: '멍멍이',
  sound: '멍멍',
  age: 2
};
console.log(Object.entries(doggy));
console.log(Object.keys(doggy));
console.log(Object.values(doggy));
  • Object.entries: [[키, 값], [키, 값]] 형태의 배열로 변환
  • Object.keys: [키, 키, 키] 형태의 배열로 변환
  • Object.values: [값, 값, 값] 형태의 배열로 변환

객체가 지니고 있는 값에 대하여 반복을 하고 싶다면 위 함수들을 사용해도 되고, for...in 구 문을 사용해도 된다.

const doggy = {
  name: '멍멍이',
  sound: '멍멍',
  age: 2
};
for (let key in doggy) {
  console.log(`${key}: ${doggy[key]}`);
}

 

연습

function sumOf(numbers) {
  let sum = 0;
  for (let i = 0; i < numbers.length; i++) {
    sum += numbers[i];
  }
  return sum;
}
const result = sumOf([1, 2, 3, 4, 5]);
console.log(result);

 


배열 자주쓰이는 내장함수

forEach문

const superheroes = ['아이언맨', '캡틴 아메리카', '토르', '닥터 스트레인지'];

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

 

map

const array = [1, 2, 3, 4, 5, 6, 7, 8];
const squared = [];
array.forEach(n => {
  squared.push(n * n);
});
console.log(squared);

//[1, 4, 9, 16, 25, 36, 49, 64];

만약 map 을 사용하면 이를 더 짧은 코드를 사용하여 구현 할 수 있다.

const array = [1, 2, 3, 4, 5, 6, 7, 8];

const square = n => n * n;
const squared = array.map(square);
console.log(squared);

 

indexOf : 원하는 항목이 몇번째 원소인지 찾아주는 함수

const superheroes = ['아이언맨', '캡틴 아메리카', '토르', '닥터 스트레인지'];
const index = superheroes.indexOf('토르');
console.log(index);

//2

 

filter

배열에서 특정 조건을 만족하는 값들만 따로 추출하여 새로운 배열 을 만듦.

splice

배열에서 특정 항목을 제거할 때 사용.

slice

배열을 잘라낼 때 사용하는데, 중요한 점은 기존 의 배열은 건들이지 않는 다는 것.

 

shift

첫번째 원소를 배열에서 추출

pop

push 의 반대,

push 는 배열의 맨 마지막에 새 항목을 추가하고, pop 은 맨 마지막 항목을 추출.

 

unshift : 배열의 맨 앞에 새 원소를 추가한다.(shift 의 반대)

concat : 여러개의 배열을 하나의 배열로 합쳐준다.

 

join : 배열 안의 값들을 문자열 형태로 합쳐준다.

const array = [1, 2, 3, 4, 5];
console.log(array.join()); // 1,2,3,4,5
console.log(array.join(' ')); // 1 2 3 4 5
console.log(array.join(', ')); // 1, 2, 3, 4, 5

 

reduce : 잘 사용 할 줄 알면 정말 유용한 내장 함수

//주어진 배열에 대하여 총합을 구해야 하는 상황
const numbers = [1, 2, 3, 4, 5];
let sum = 0;
numbers.forEach(n => {
  sum += n;
});
console.log(sum);

//15
//reduce로 구현
const numbers = [1, 2, 3, 4, 5];
let sum = array.reduce((accumulator, current) => accumulator + current, 0);
console.log(sum);

accumulator 는 누적된 값을 의미

 

//평균도 구할 수 있다.
const numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((accumulator, current, index, array) => {
  if (index === array.length - 1) {
  return (accumulator + current) / array.length;
  }
  return accumulator + current;
}, 0);
console.log(sum);

//3