[DAY9] 알수록 어려운 함수

Jhey·2024년 10월 24일
0

JavsScript

목록 보기
4/18

함수

함수 특징

  1. 보편적으로 const를 많이 사용한다.
    • 재할당할 일이 거의 없어서
  2. 재활용성이 좋다, 어디서든 호출해서 쓸 수 있다.

함수 선언문과 함수 표현식

// 함수 선언문
function gugudan() {
  // code block
}

// 함수 표현식
// 변수를 선언하는 것
// 변수에 넣어서 미리 파악하기 어려움, 그래서 변수의 이름으로 호출을 해야 한다.
const A = function gugudan() { 
  // code block
}
gugudan(); // 함수 선언문 호출
A(); // 함수 표현식 호출

화살표 함수 (함수 표현식)

// 변수 이름을 생략한다.
const gagadan = () => {};

// 매개변수가 한 개일 때는 소괄호를 생략해도 된다.
const gagadan = dan => {};

매개변수

// end=20 이렇게 기본값을 설정할 수 있다.
function gugu(d, start, end = 20) { }

gugu(3, 2); // 인자

반환값 (return)

const sum = (c) => { // 함수 내부 공간
  const result = c;
  return result; // 반환값이다
}
const result = sum(10); // 함수 외부 공간
console.log(result);

// 함수 내부 공간과 외부 공간은 다르다고 생각하기 때문에
// 이름이 같은 식별자를 사용할 수 있었던 것임

// 매개변수 반환값
const sum = (v) => v;
// 화살표 함수를 사용해 극단적으로 줄여서 사용할 수 있음

const s = () => ({name: "철수"});
// 객체를 return하고 싶다면 소괄호()를 사용하여 즉시 반환하자

// 즉시 함수 중단
function a(s) {
  if(s === 3) {
    return; // 함수를 중단하는 역할, undefined를 반환한다
  }
}

가변 인자

// 재사용성을 높이기 위해 사용한다.

const sum = (n1, n2, n3) => n1 + n2 + n3;
console.log(sum(10, 30, 30));
// 위처럼 호출 시 재사용성이 아쉬움. 4개를 하면? 2개를 하면? 실행 안됨.
// 그래서 사용해볼 수 있는 가변 인자 arguments

function sum() {
  console.log(arguments);
  // arguments라는 속성만 참고하겠다는 의미
  // arguments는 매개변수가 몇 개가 왔는지 알려준다.
  for (let value of arguments) {
    sum += value;
  }
  // 매개변수 갯수에 구애받지 않을 수 있다.
}
  • 화살표 함수는 arguments를 사용할 수 없다.
    • '…' 전개 연산자 스프레드 연산자를 사용해 할 수 있다.
    • 전개 연산자?
      • 명시적으로 매개변수를 받지 않았을 때 사용한다.
      • 배열 형태로 받아준다.
      • 매개변수에서 마지막에 와야 한다.
const sum = (...args) => {
  console.log(args);
};

스코프

식별자를 참조할 수 있는 범위

function a() { // 스코프
  const a = "D";
}

console.log(a); // 접근할 수 없음, 스코프 때문에
  • 전역 스코프

    전역 스코프는 블록 바깥이나 함수 바깥에 선언된 변수다.
    어떤 위치에서도 사용할 수 있다.

const a = "전역변수"; // 전역 스코프에 선언
function temp() { 
  const str = a;
}
console.log(temp()); // "전역변수" 라고 호출된다.
  • 지역 스코프

    코드의 특정 부분에서만 사용할 수 있는 변수다.
    함수 스코프와 블록 스코프 두 가지가 있다.

    • 함수 스코프

      function() {
        // 함수 스코프
        const b = 20;
      }
      console.log(b); // not defined, 함수 스코프 안에 선언된 변수를 호출해서
    • 블록 스코프

      {
        // 블록 스코프
        // var 사용 금지!!! 적용이 되지 않는다.
        const b = 20;
      }
      console.log(b); // not defined, 블록 스코프 안에 선언된 변수를 호출해서
  • 특징

    • 지역 스코프에서 전역 스코프를 호출하는 건 가능하다.
    • 전역 스코프에서 지역 스코프를 호출하는 건 불가능하다.
      • 개인(지역)은 연예인(전역)을 알지만 연예인(전역)은 개인(지역)을 알기 어렵다.

스코프 퀴즈

Q1. 각 a의 호출 값은?

const a = 5;

function testScope() {
  console.log(a);  // 5
  {
    const a = 10;
    console.log(a);  // 10
  }
  console.log(a);  // 5
}

testScope();

Q2. 각 count의 호출 값은?

let count = 5;

function increase() {
  count++;  
  console.log(count);  // 오류
  let count = 10; 
  console.log(count);  // 오류
}

increase();

의문점

  • 왜 두 문제 다 전역 스코프에 변수를 선언했는데 결과가 다를까?

이유

  • 문제 2번은 함수 내부에서 let count가 선언될 예정이기 때문에, 함수 스코프 내에서 상위 스코프(전역 스코프)의 변수를 참조하지 않는다. 하지만 선언 전에 변수에 접근하려 하다 TDZ에 걸려 오류가 발생.

    TDZ?

    let이나 const로 변수를 선언할 때, 변수가 선언되기 전에 그 변수에 접근하려고 하면 참조 오류가 발생하는 상태

let count = 5;  // 전역 변수 'count' 선언

function increase() {
  // 여기부터 TDZ 시작: 함수 스코프 내에서 'count'가 아직 선언되지 않았음
  count++;  // TDZ에 걸림! 오류 발생 (ReferenceError)
  console.log(count);
  
  let count = 10;  // 여기서 'count'가 선언됨 (TDZ 종료)
  console.log(count);  
}

increase();

배운 점

  1. 반복문, 조건문에 이어 함수까지 배우면서 실습을 많이 하게 되는데 확실히 사고력을 많이 단련해야겠다는 생각이 든다. 그리고 평소 메소드를 사용해 풀다가 사용하지 않고 풀어보려니 은근 어렵다. 역시 무엇이든 의존하면 안 된다.
  2. 스코프를 배워보니 평소에 '감'으로 코딩을 했다는 생각이 든다. 정확한 명칭과 이유를 공부해보니 지금까지 왜 그렇게 사용했는지 알게 되어서 너무 좋다.
profile
천천히 가더라도 즐겁게 ☁

0개의 댓글

관련 채용 정보