모던 자바스크립트 Deep Dive - 12. 함수 & 수업내용 추가 정리

지영·2021년 12월 11일
1

JavaScript

목록 보기
11/37
post-thumbnail

함수


12.1 함수란?

  • 프로그래밍 언어의 함수는 일련과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것이다
  • 함수는 값이며, 식별자인 함수 이름을 사용할 수 있다
  • 함수는 함수 정의를 통해 생성한다
  • 인수를 매개변수를 통해 함수에 전달하면서 함수의 실행을 명시적으로 지시해야 한다. 이를 함수 호출이라 한다.

12.2 함수를 사용하는 이유

  • 함수는 객체 타입의 값이다. 따라서 이름을 붙일 수 있다.

12.3 함수 리터럴

  • js의 함수는 객체 타입의 값이다
  • 함수도 식별자 네이밍 규칙을 준수해야 한다
  • 매개변수도 변수와 마찬가지로 식별자 네이밍 규칙을 준수해야한다
  • 함수 리터럴도 평가되어 값을 생성하며, 이 값은 객체이다. 즉 함수는 객체이다.
  • 일반 객체는 호출할 수 없지만 함수는 호출할 수 있다
  • 그리고 일반 객체에는 없는 함수 객체만의 고유한 프로퍼티를 갖는다

12.4 함수 정의

  • 정의된 함수는 자바스크립트 엔진에 의해 평가되어 함수 객체가 된다.

변수 선언과 함수 정의

  • 함수 선언문이 평가되면 식별자가 암묵적으로 생성되고 함수 객체가 할당된다
  • 변수에는 선언, 함수에는 정의라고 표현한다.

12.4.1 함수 선언문

  • 함수 선언문은 함수 리터럴과 형태가 동일하다
  • 함수 리터럴은 함수 이름을 생략할 수 있으나 함수 선언문은 함수 이름을 생략할 수 없다
  • 함수 선언문은 표현식이 아닌 문이다.
  • 표현식이 아닌 문은 변수에 할당할 수 없다
  • 함수선언문도 표현식이 아닌 문이므로 변수에 할당할 수 없다
  • 하지만 함수 선언문은 함수 이름을 생략할 수 없다는 점을 제외하면 함수 리터럴과 형태가 동일하다.
    이는 기명 함수 리터럴은 함수 선언문 또는 함수 리터럴 표현식으로 해석될 가능성이 있다는 의미이다.
  • 가명 함수 리터럴은 중의적인 코드이다.
  • 함수 리터럴을 단독으로 사용하면 함수 선언문으로 해석하고
  • 함수 리터럴을 변수에 할당하거나 피연산자로 사용하면 함수 리터럴 표현식으로 해석한다
  • 함수는 함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출한다

12.4.2 함수 표현식

  • 값의 성질을 갖는 객체를 일급 객체라 한다
  • Js의 함수는 일급 객체이다.
  • 함수를 값처럼 자유롭게 사용할 수 있다는 의미이다
  • 함수 선언문은 '표현식이 아닌 문'이고, 함수 표현식은 '표현식인문'이다

12.4.3 함수 생성 시점과 함수 호이스팅

  • 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 함수 호이스팅이라 할 수 있다
  • 런타임 이전의 자바스트립트 엔진에 의해 먼저 실행되어 식별자를 생성한다는 점에서 동일하다
  • var 키워드로 선언된 변수는 undefined로 초기화되고, 함수 선언문을 통해 암묵적으로 생성된 식별자는 함수 객체로 초기화된다

12.4.4 Function 생성자 함수

  • 생성자 함수는 객체를 생성하는 함수를 말한다
  • 생성자 함수로 함수를 생성하는 방식은 일반적이지 않으며 바람직하지도 않다
  • 생성자 함수는 클로저를 생성하지 않는 등... 함수 선언문이나 함수 표현식으로 생성한 함수와 다르게 동작한다

12.4.5 화살표 함수

  • 화살표 함수는 항상 익명 함수로 정의한다
  • 화살표 함수는 기존의 함수보다 표현만 간략한 것이 아니라 내부 동작 또한 간략화되어 있다

12.5 함수 호출

  • 기존 함수와 this 바인딩 방식이 다르고 prototype 프로퍼티가 없으며 argumetns 객체를 생성하지 않는다

12.5.1 매개변수와 인수

  • 함수를 실행하기 위해 필요한 값을 함수 외부에서 함수 내부로 전달할 필요가 있는 경우, 매개변수를 통해 인수를 전달한다
  • 인수는 값으로 평가될 수 있는 표현식이어야 한다
  • 매개변수는 함수 몸체 내부에서 변수와 동일하게 취급된다
  • 매개변수의 스코프는(유효 범위)는 함수 내부다
  • 함수를 호출할 때 매개변수의 개수만큼 인수를 전달하는 것이 일반적이지만 그렇지 않은 경우에도 에러가 발생하지는 않는다
  • 인수가 할당되지 않은 매개변수의 값은 undefined이다
  • 매개변수보다 인수가 더 많은 경우 초과된 인수는 무시된다

12.5.2 인수 확인

  • 자바스크립트의 경우 함수를 정의할 때 적절한 인수가 전달되었는지 확인할 필요가 있다
  • 타입스크립트와 같은 정적 타입을 선언할 수 있는 자바스크립트의 상위 확장을 도입해서 컴파일 시점에 부적절한 호출을 방지할 수 있게 하는 것도 하나의 방법이다

rest parameter

  • ES6에서 도입된 매개변수 기본값을 사용하면 함수 내에서 수행하던 인수 체크 및 초기화를 간소화 할 수 있다.
  • 매개변수 기본값은 매개변수에 인수를 전달하지 않았을 경우와 Undefined 를 전달한 경우에만 유효하다

12.5.3 매개변수의 최대 개수

  • 이상적인 함수는 한 가지 일만 해야 하며 가급적 작게 만들어야 한다

12.5.4 반환문

  • 함수는 retrun 키워드를 사용해 js에서 사용 가능한 모든 값을 반환할 수 있다
  • 함수 호출은 표현식이다 (값이 아닌 표현식)
  • 함수 호출 표현식은 return 키워드가 반환한 표현식의 평가 결과, 즉 반환값으로 평가된다
  • return 키워드 뒤에 반환값으로 사용할 표현식을 명시적으로 지정하지 않으면 undifined 가 반환된다
  • 반환문은 생략할 수 있다. 이때 함수는 함수 몸체의 마지막 문까지 실행한 후 암묵적으로 undefined를 반환한다

12.6 참조에 의한 전달과 외부 상태의 변경

  • 객체를 불변 객체로 만들기 위해 객체의 복사본을 새롭게 생성하여 객체를 마치 원시값처럼 변경 불가능한 값으로 동작하게 만들 수 있다.
  • 이를 통해 객체의 상태 변경을 원천봉쇄하고 객체의 상태 변경이 필요한 경우에는 객체의 방어적 복사를 통해 원본 객체를 완전히 복제, 즉 깊은 복사를 통해 새로운 객체를 생성하고 재할당을 통해 교체한다. 이를 통해 외부 상태가 변경되는 부수 효과를 없앨 수 있다
  • 외부 상태를 변경하지 않고 외부 상태에 의존하지도 않는 함수를 순수 함수라 한다
  • 순수 함수를 통해 프로그램의 안정성을 높히려는 프로그램밍 패러다임을 함수형 프로그래밍이라 한다

12.7 다양한 함수의 형태

12.7.1 즉시 실행 함수

  • 함수 정의와 동시에 즉시 호출되는 함수
  • 즉시 실행 함수 내에 코드를 모아두면 혹시 있을 수도 있는 변수나 함수 이름의 충돌을 방지할 수 있다

12.7.2 재귀 함수

  • 함수가 자기 자신을 호출하는 것을 재귀 호출이라 한다
  • 재귀 호출한 함수는 자신을 무한 재귀 호출한다. 따라서 재귀함수 내에는 재귀 호출을 멈출 수 있는 탈출 조건을 반드시 만들어야 한다
  • 대부분의 재귀 함수는 for문이나 while문으로 구현 가능하다
  • 재귀 함수는 반복문을 사용하는 것보다 재귀함수를 사용하는 편이 더 직관적으로 이해하기 쉬울 때만 한정적으로 사용하는 것이 바람직하다

12.7.3 중첩 함수

  • 함수 내부에 정의된 함수를 중찹 함수 또는 내부 함수라 한다
  • 중첩 함수는 스코프와 클로저에 깊은 관련이 있다

12.7.4 콜백 함수

  • 함수의 변하지 않는 공통 로직은 미리 정의해 두고, 경우에 따라 변경되는 로직은 추상화해서 함수 외부에서 함수 내부로 전달할 수 있다
  • 이를 통해 함수는 내부 구조에 강력히 의존하지 않고 외부에서 로직의 일부분을 함수로 전달받아 수행하므로 더욱 유연한 구조를 갖는다
  • 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수를 콜백함수라고 하며, 매개 변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수를 고차함수라고 한다.
  • 고차함수는 콜백함수를 자신의 일부분으로 합성한다.

    고차함수는 매개변수를 통해 전달받은 콜백 함수의 호출 시점을 결정해서 호출한다.
    콜백함수는 고차 함수에 의해 호출되며, 이때 고차 함수는 필요에 따라 콜백 함수에 인수를 전달할 수 있다.
    따라서 고차 함수에 콜백 함수를 전달할 때 콜백 함수를 호출하지 않고 함수 자체를 전달해야 한다.

  • 콜백 함수를 다른 곳에서도 호출할 필요가 있거나, 콜백 함수를 전달받는 함수가 자주 호출된다면 함수 외부에서 콜백 함수를 정의한 후 참조 함수를 고차 함수에 전달하는 편이 효율적이다
  • 콜백 함수는 비동기 처리에 활용되는 중요한 패턴이다.
  • 콜백 함수는 배열 고차 함수에서도 사용된다

12.7.5 순수 함수와 비순수 함수

  • 순수 함수는 어떤 외부 상태에도 의존하지 않고 오직 매개변수를 통해 함수 내부로 전달된 인수에게만 의존해 반환값을 만든다
  • 순수 함수의 특징은 함수의 외부 상태를 변경하지 않는다
  • 순수 함수는 어떤 외부 상태에도 의존하지 않으며 외부 상태를 변경하지도 않는 함수이다
  • 외부 상태에 의존하는 함수를 비순수 함수라고 한다
  • 함수의 외부 상태를 변경하는 부수 효과가 있다
  • 비순수 함수는 외부 상태에 의존하거나 외부 상태를 변경하는 함수다
  • 자바스크립트는 멀티 패러다임 언어이므로 객체지향 프로그래밍 뿐만 아니라 함수형 프로그래밍을 적극적으로 활용하고 있다
  • 함수형 프로그래밍은 결국 순수함수를 통해 부수 효과를 최대한 억제해 오류를 피하고 프로그램의 안전성을 높이려는 노력의 일환이라 할 수 있다

함수

  • 함수 {}중괄호를 '함수 바디'라고 한다
  • 함수에는 입력값과 출력값이 있다
  • return으로 출력(반환)
  • break문이 그러하듯 바디에서 return을 만나면 함수는 반환값을 반환하며 함수를 종료시킨다
  • 매개변수를 이용하여 함수에 입력값을 줄 수 있다
  • 변수는 접근할 수 있는 범위가 있다
  • 함수도 마찬가지로 유효범위 때문에 함수 외부에서 함수 내부로 접근할 수 없다
  • 외부에서 함수에 접근하려면 매개체 역할을 하는 변수를 사용해 함수 내부로 값을 전달할 수 있도록 할 수 있다
  • 매개변수(파라미터)를 통해 함수에 접근한다
  • 매개변수는 함수 호출시 매개변수 자리값에 맞게 인자값(argument)을 넘겨준다

rest parameter

  • 얕은 복사시 사용한 ...(spread 연산자)와 비슷하다
  • 함수 정의시 매개변수를 선언해야 인자를 넘길 수 있다
  • ...(rest parameter)로 나머지 매개변수를 선언하지 않은 나머지 인자들을 배열로 만든다
  • ...(rest parameter)앞에 매개변수가 있다면 그 매개변수에 인자가 먼저 넘겨지고 들어갈 매개변수가 없는 나머지 인자들은 ...(rest parameter)가 있다면 해당 매개변수에 들어가 배열의 원소가 된다

함수 사용시 헷갈리는 부분

return과 console.log()

  • console.log()는 그저 콘솔에 원하는 내용을 출력하는 방법이다
  • return을 하지 않았다면 출력을 해 주지 않은 상황이다
  • 하지만 반드시 return 해야만 하는 것은 아니다
  • 바꿔주는 동작 같은 것만 하는 경우 함수 밖으로 값을 출력할 필요가 없다
  • 하지만 값을 출력(반환)해야 할 경우 반드시 return 해준다

function keyword - argument객체

  • function은 arguments라는 객체가 내장되어있다
  • arguments는 유사 배열 객체이다
  • 하지만 rest parameter가 있기 때문에 요즘은 사용하지 않는다(rest parameter은 배열이므로 rest parameter[index]와 같이 사용이 가능하기 때문이다)
  • function키워드로 함수 정의시에만 arguments객체를 사용 가능하다
  • 화살표 함수로 함수를 정의했을 경우 사용할 수 없다

arrow function

  • 화살표 함수 정의시 매개변수가 하나라면 ()로 묶을 필요 없다
  • 다른 동작 없이 바로 return하는 경우 아래와 같은 코드로 작성할 수 있다
const bar = 매개변수 => 매개변수 + 2;
  • 하지만 동작을 바디에 추가한다면 기존의 화살표 함수처럼 사용해야 한다

익명함수

  • 이름이 없는 함수
  • 콜백함수(함수의 인자로 들어가는 함수)로 익명함수를 사용할 수 있다
  • 한번 실행 후 사용하지 않을 함수일 경우 사용할 수 있다

즉시 실행 함수

  • 함수를 선언과 동시에 바로 실행시키는 함수
  • 함수를 ()소괄호 로 묶고 그 함수를 ()로 바로 호출한다
  • 함수 선언과 동시에 호출하는 것
  • jquery나 script함수(?) 사용시 즉시 실행 함수로 사용하는 것과 마찬가지이다

익명함수와의 차이점

  • 익명함수는 함수 선언만 하고 호출은 하지 않는다
  • 즉시 실행 함수는 함수 선언과 호출을 동시에 한다

    함수에 식별자가 필요하지 않다면 익명함수를 사용하고,
    식별자도 필요하지 않고 바로 실행이 가능한 함수를 사용하고 싶다면 즉시 실행 함수를 사용할 수 있다


콜백함수

  • 함수의 인자값으로 넘기는 함수(함수의 인자인 함수)
  • 결과적으로 콜백함수는 매개변수에 어떤 인자값을 넘길 때 그 인자값으로 함수를 넘긴다는 의미이다
  • 인자로 넘긴 함수를 콜백함수로 받은 함수의 바디 안에서 사용할 수 있다
  • 인자로 함수를 호출하며 넘기는 것 과 콜백함수로 인자를 넘기는 것은 전혀 다르다
  • 콜백함수는 어떤 함수의 바디 안에서 호출된다
  • 타입 스크립트 에서는 타입을 정할 수 있다(어떤 타입으로 retrun되어야 하는지까지 정할 수 있다)

배열의 반복

for (let i = 0; i < Array.length - 1; i++){
 ...
}
  • Array.length -1은 배열의 인덱스 번호(원소 수)만큼만 배열을 한번 순환하겠다는 의미이다
  • 배열의 처음부터 끝까지의 인덱스 번호를 모두 순회하고 싶다면 반복문의 초기값이 0부터 시작되어 Array.length에 -1을 해줘야 인덱스 0부터 배열의 마지막 인덱스까지를 순환할 수 있다

재귀 함수

  • 자기 자신을 호출하는 함수
  • while문과 유사하다 -> true라면 무한 반복 된다
  • while문은 break할 수 있는 트리거가 있어야 하는 것 과 같이 재귀 함수도 무한 반복이 될 수 있기 때문에 탈출할 방법을 만들어 놔야 한다

  • 함수 안에 있는 조건문이나 반복문에서 return될 경우 해당 문이 있는 함수 자체에서 return되어 함수를 빠져나간다

고차 함수

  • 함수를 반환하는 함수이다
  • 나중에 언제 사용하는지 알려주신다 하심!!

12.2 함수를 사용하는 이유

  • 함수는 재사용이 용이하다
  • 식별자를 통해 이 함수가 어떤 역할을 하는 함수인지 판단할 수 있다. 따라서 코드 가독성이 높아진다
  • 유지보수의 편의성을 높일 수 있다

12.3 함수 리터럴

  • 화살표 함수나, funcion 식별자 와 같은 형태로 주로 사용한다
  • 일반적인 함수의 식별자는 camel case를 사용한다
  • 생성자 함수의 식별자는 pascal case를 사용한다

12.4 함수 정의

12.4.2 함수 표현식

  • 사용하지 않는다
  • 화살표 함수나, funcion 식별자 와 같은 형태로 주로 사용한다

12.4.3 함수 생성 시점과 함수 호이스팅

  • 호이스팅 -> 끌어올림
  • 함수 선언문으로 함수를 정의하면 런타임 이전에 함수 객체가 먼저 생성된다

12.5 함수 호출

12.5.1 매개변수와 인수

  • 함수에 default parameter를 지정해 줄 수 있다
  • 함수 호출시 해당 자리에 인자값을 준다면 default parameter에선 인자값으로 치환된다
  • 예제 12-19 argument는 잘 사용하지 않는다

  • 매개변수도 만들어지는 순간 선언하는 것이다
  • 매개변수에 인자값을 넘기지 않는다면(할당하지 않는다면) undefined이다

  • 함수가 복잡해지면 매개변수 순서에에 맞춰 인자를 주는 것이 매우 헷갈린다
  • 이런 경우 인자로 객체를 주고 객체를 인자로 받은 해당 함수의 바디 안에서는 객체의 프로퍼티를 이용하면 순서를 신경쓰지 않고 인자로 받은 객체의 프로퍼티를 이용할 수 있다

12.7 다양한 함수의 형태

12.7.2 재귀 함수

  • 팩토리얼 함수를 만들 수 있다(알아보기)

  • 고차함수는 당장 알지 못해도 괜찮다(매개변수를 통해 함수의 외부에서 콜백함수를 전달받은 함수를 고차 함수라고 한다)

12.7.5 순수 함수와 비순수 함수 -> 중요

  • 함수의 인자로 주는 값(입력 값)이 동일하다면 매변 같은 값이 출력되야 한다
  • 이 때 어떤 의존 값이 붙는다면 -> 이때부터는 이 함수를 순수하지 않은 비순수 함수라고 한다
  • 함수 외부의 값을 함수 내부로 끌어와서 사용하는 경우 외부의 값이 바뀌는 것에 따라서 함수의 출력값이 바뀔 가능성이 존재한다
  • 함수형 프로그래밍의 기본은 순수함수를 사용하는 것이다(알아보기)
profile
천천히 운영되는 개발 블로그

0개의 댓글