[Tip] function 은 되도록 사용하지 마세요.

2022. 11. 4. 21:07·프로그래밍 언어/JavaScript

다양한 곳에서 사용되어 오히려 헷갈리는 기존 function 키워드

예시 1) 일반 함수로 활용

출력 결과는 다음과 같습니다.

여기서 this 는 window 를 가리킵니다.

예시 2) 생성자 함수로 활용

출력 결과는 다음과 같습니다.

여기서 가리키는 this 는 Func 클래스에 의해 만들어진 인스턴스입니다.

this 가 windows 가 아니기 때문에 func 라고 하는 인스턴스에 프로퍼티 args 를 만들어서 거기에 배열을 담고 있게 됩니다.

예시 3) 객체 메소드로 활용

출력 결과는 다음과 같습니다.

객체에 있는 메소드를 실행했을 때 this 는 . 앞에 있는 bar 가 됩니다.

위와 같이 function 키워드는 일반 함수로도 객체 생성자 함수로도 객체 메서드로 활용될 수 있다 보니 범용적으로 쓸 수 있다는 측면에서는 좋습니다. 

하지만 오히려 이게 문제를 일으킬 수도 있습니다.

 

function 키워드를 사용하여 a 함수를 선언 후 콘솔로 값을 출력해보았는데요.

a 함수는 arguments 를 비롯해서 다양한 프로퍼티를 가지고 있음을 알 수 있습니다.

이 프로퍼티들이 위의 예시에서 모두 사용되는 것은 아닙니다.

일반 함수로 활용되는 경우, prototype 프로퍼티는 불필요합니다. prototype 프로퍼티는 생성자 함수로 활용되는 경우에만 필요합니다.

객체 메서드로 활용되는 경우, this 바인딩에 의해 this 가 해당 객체를 가리키게 됩니다.

참고) this 는 실행 컨텍스트 생성 시점에 할당됩니다.

이는 this 를 쓸 경우에는 좋지만 함수로 쓸 때는 불필요한 정보입니다.

this 는 동적으로 바인딩되기 때문에 이는 오히려 혼란을 가중시킬 수 있습니다. 

 

그래서 ES2015에서는 일반 함수로 활용, 생성자 함수로 활용, 객체 메서드로 활용할 때 그 목적에 맞는 정확한 기능들이 추가되었습니다.

function 키워드를 대체할 ES 2015 문법 살펴보기

1. class 의 등장

function 키워드로 선언한 생성자 함수

출력 결과 :

function 키워드로 선언한 생성자 함수에 할당된 getArgs 함수는 enumerable 값이 true 로 설정됩니다.

이에 따라 for ... in 문을 통해 생성자 함수의 프로퍼티를 순회할 때 getArgs 함수가 반복 출력됩니다.

 

생성자 함수의 프로퍼티 순회 시 프로토타입에 있는 프로퍼티를 제외시키고 싶다면(여기서는 getArgs 함수), 다음과 같이 따로 조건문을 설정해줘야 합니다. 

반면, class 키워드로 선언언한 클래스에 선언한 getArgs 메서드는 enumerable 값이 false 로 설정됩니다.

for ... in 문을 통해 클래스의 프로퍼티를 순회할 때 getArgs 함수가 반복 출력되지 않습니다. 

 클래스는 hasOwnProperty 메소드를 따로 사용하지 않아도 객체 인스턴스 자신에게 있는 값만 순회를 돌 수 있어 개발자가 신경써야 할 부분이 줄어들었습니다.

 

function 키워드로 선언한 Func 생성자 함수와 class 키워드로 선언한 Bar 클래스 자체 비교

- Func 의 경우 arguments 값을 출력하지만, Bar 의 경우 위와 같은 에러를 던집니다.

- Func 의 경우 함수, 객체 생성자로 사용할 수 있어 new 키워드 없이도 호출될 수 있지만 Bar 의 경우 new 키워드 없이 호출될 수 없습니다.

 

결론 : 객체 생성자 함수를 선언할 때는 class 키워드를 사용하라.

2. arrow function

내가 가지고 있었던 오해) arrow function 을 간략한 함수일 경우에만 사용하고 나머지 경우에는 function 키워드를 사용한다.

function 키워드로 선언한 함수와 arrow function 으로 선언한 함수 비교

출력 결과는 다음과 같습니다.

arrow function 은,

- prototype 이 없어 생성자로 사용할 수 없습니다.

- arguments 프로퍼티 값 접근 시 반드시 getter 를 호출해야 합니다.

- this 바인딩을 하지 않습니다.

- call, apply 메서드로도 this 바인딩을 할 수 없습니다.

 

애초부터 함수로 사용한다고 하면 this를 신경 쓸 이유가 없습니다.

this 를 써야 된다면 객체 메서드 선언 방식을 쓰면 됩니다.

결론 :  this 를 신경쓰지 않고 일반 함수로만 사용한다면 arrow function 을 사용하자.

 3. 메서드 축약형

function 키워드로 선언한 객체 메서드와 메서드 축약형으로 선언한 객체 메서드 비교

출력 결과는 다음과 같다.

메서드 축약형으로 선언한 객체 메서드는,

- prototype 이 없어 생성자 함수로 쓸 수 없습니다.

- arguments 프로퍼티 값 접근 시 반드시 getter 를 호출해야 합니다.

- arrow 함수와 다르게 this 바인딩이 됩니다.

 

각 객체 별로 선언한 메서드를 호출한 결과는 다음과 같습니다.

각 객체 별 name 프로퍼티 값이 정상적으로 출력됨을 알 수 있습니다. 

예외적으로 반드시 function 키워드를 사용해야 하는 경우) generator

함수 형태의 generator 에서만 이 function 키워드가 필요합니다.

객체 안에서 generator 를 만들 경우는 다음과 같습니다. (메서드 축약형 사용)

 

이 생김새 그 자체만으로도 다른 가능성이 있다는 걸 열어두지 않고 한 가지 기능만 할 것이라고 생각하는 것이 다른 사람이 내 코드를 봤을 때 좀 더 빨리 이해할 수 있는 지름길이라고 생각합니다.

정리

기존 함수는 다양한 목적에 두루 쓸 수 있는 만능 키워드입니다.

무겁고, 상황에 따라 개발자가 추가로 번거로운 작업을 해줘야 하거나 안전장치를 마련해야 하는 등의 문제가 있습니다.

그러므로,

함수로 쓰고자 할 때는 arrow function 사용

생성자 함수로 쓰고자 할 때는 class 사용

메서드로 쓰고자 할 때는 method 축약형 사용

을 권장합니다.

function 키워드는 generator 를 선언하는 경우를 제외하고는 거의 쓰이지 않습니다.

 

참조

[JavaScript 미세팁] function은 아예 쓰지 마세요 : https://www.youtube.com/watch?v=LPEwb5plEoU 

'프로그래밍 언어 > JavaScript' 카테고리의 다른 글

[JavaScript] Primitive Type(원시 타입) 과 Reference Type(참조 타입)  (0) 2022.11.05
[JavaScript] 자바스크립트 언어의 특징  (0) 2022.11.05
[JavaScript] for, foreach, filter, map, reduce 기능 및 퍼포먼스의 차이  (2) 2022.09.24
Generator  (0) 2020.11.23
JavaScript와 Iterator  (0) 2020.11.23
'프로그래밍 언어/JavaScript' 카테고리의 다른 글
  • [JavaScript] Primitive Type(원시 타입) 과 Reference Type(참조 타입)
  • [JavaScript] 자바스크립트 언어의 특징
  • [JavaScript] for, foreach, filter, map, reduce 기능 및 퍼포먼스의 차이
  • Generator
rondeveloper
rondeveloper
  • rondeveloper
    Ron's learning record
    rondeveloper
  • 전체
    오늘
    어제
    • 분류 전체보기 (99)
      • k8s (1)
      • AWS (1)
      • 리눅스 (3)
      • Docker (8)
      • 라이브러리 & 프레임워크 (14)
        • React (2)
        • NestJS (8)
        • Spring (0)
        • Django (3)
        • FastAPI (1)
      • 웹 (2)
        • Nginx (1)
      • 프로그래밍 언어 (29)
        • HTML (0)
        • CSS (0)
        • JavaScript (21)
        • Python (3)
        • Node.js (0)
        • TypeScript (4)
        • Java (1)
      • Today I learned (9)
      • 알고리즘 (9)
        • 백준 (0)
        • 프로그래머스 (8)
        • 개념 (1)
      • 티끌모아 태산 (5)
        • 하루에 영단어 하나씩 (5)
        • 독서 (0)
      • 시행착오 (3)
      • 데이터베이스 (2)
        • MySQL (0)
      • 컴퓨터 과학 (8)
        • 네트워크 (2)
        • 운영체제 (0)
        • 데이터베이스 (2)
        • 자료구조 (4)
      • 포트폴리오 (4)
        • JJINCAFE IN SEOUL (4)
        • CODEUNICORN (0)
      • 회고 (0)
      • CICD (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Docker
    조인
    자바스크립트
    생활코딩
    Kubectl
    mysql
    레벨2
    도커
    코딩테스트
    IP 주소
    javascript
    기초
    FastAPI
    iterable
    스택
    네트워크
    Kubernetes
    typeorm
    프로그래머스
    모듈
    컨테이너
    redis
    리눅스
    typescript
    쿠버네티스
    배열
    django
    nestjs
    Til
    Python
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
rondeveloper
[Tip] function 은 되도록 사용하지 마세요.
상단으로

티스토리툴바