ETC

딱히 구분할 필요는 없지만 다른, 그런 것들

partner_jun 2023. 9. 24. 15:37

개발자로서 업무를 진행하다 보면 별 생각 없이 섞어 쓰는 단어들이 있다. 정확한 뜻은 다르지만 모두 이해하고 있고 구분할 정도로 다르지는 않기에 다들 무시하는 그런 단어들이다. 섞어 쓰면 안된다거나 고쳐야 한다는 그런 것은 아니고, 단순히 재미삼아 떠오르는 대로 몇가지 적어본다.
 


 

1. Function과 Method

최근 멀티 패러다임 언어가 많아지며 이 둘을 구분하는 것이 꽤 중요해지긴 했다. 자신이 어떤 것을 만들고자 하는지 알아야 방향을 잡을 수 있기 때문이다. 간단하게 요약하면 이렇게 쓸 수 있겠다.

  • 함수는 외부에 영향 없이 입력에 대한 출력을 반환하는 명령이다. 
  • 메소드는 요소(객체)의 상태를 변화시키는 행동이다.

 

가장 많은 추천을 받은 Stackoverflow의 답변

 
함수형 언어를 공부했다면 이 두개 단어를 혼용하는 것에 미묘한 반감을 가지게 된다. 함수형에서 가장 처음 강조하는 것이 순수한 함수이기 때문일 것이다. 처음 배우는 프로그래밍 언어가 무엇이냐에 따라 가지는 기본적인 인식이 달라지겠지만, 가장 쉽게 익히는 객체형 언어의 특성상 대부분의 함수를 메소드처럼 작성하게 된다.
 
리액트 문서에서도 재미있는 것을 발견할 수 있다. 리액트의 훅을 자바스크립트 함수라고 표현하는 것이다.
 

상태를 변화(useState)시키고 다른 변수에 의존성을(deps) 가지는... 함수?

 
사실 훅은 훅이다. 상태를 변화시키고 의존성을 가지고 있으며, 렌더링 여부에 따라 다시 실행되기도 하는 것은 함수라고 부르기 어렵다. 굳이 따지자면 자바스크립트에서 클래스를 사용하지 않으면 모두 함수이니, '순수하지 않은' 함수라고 표현하는 것이 더 맞을 수 있겠다.
 
 
 

2. null 과 undefined, 그리고 void 0

자바스크립트 특성상 셋 다 부정 값으로 다루다보니 혼란스러워진다. 하지만 따져보면 Null은 값이 '없는' 것이고, undefined는 '정의되지 않은' 것이다.
예를 들어 "점심 뭐 먹으러 갈래?" 라고 물었을 때 아래와 같이 답할 수 있다.
 

"점심 뭐 먹으러 갈래?"에 대한 대답상태
"응"true
"아니"false
"몰라"null
아직 물어보지 않았음undefined

물어보지 않은 것과 "몰라"는 절대 같지 않다

 
개발 중엔 이 관계가 모호하다 보니 많은 사람들이 undefined 자체를 사용하지 않는 경우가 많다. 하지만 특정 상황에서는 사용하는 것이 오히려 더 명확할 수 있다. SSR을 하는 경우를 예로 들 수 있다. 클라이언트에서 실행되어 화면의 너비를 저장하는 상태가 있다고 치자. 이 때 서버 사이드에서 실행되는 코드에서는 너비가 어떻게 될까? 물론 흔히 사용하듯 null로 처리할 수 있다. 하지만 window 객체에 접근이 가능한지 엄격하게 처리해야 하는 상황이라면 아래와 같은 코드로 처리할 수도 있다.
 

윈도우 객체에 접근할 수 없는 경우를 null로 표기한다

 
물론 단순한 예시에 불과하지만 이런 식으로 undefined의 정의에 맞는 사용이 가능하다는 것은 기억할 필요가 있다. 물론 프로젝트의 특성에 따라 유지보수에 도움이 안 된다면 이런 코드는 쓰레기에 불과해진다.
 
void는 아주 특이한데, 뒤에 이어질 연산을 실행한 후 undefined를 반환하는 일종의 '고차함수'라고 할 수 있다. 간간히 사용하는 void 0 구문은 '0' 연산을 실행한 후 undefined를 반환하는 구문인 것이다. 그렇기 때문에 0이 아닌 다른 값을 넣을 수도 있다.
 

이런 예측하기 어려운 구문도 가능하다

 
트랜스파일링된 코드엔 가끔 보이지만 의도적으로 이렇게 쓰는 경우는 없을 것이다. 그래도 for(;!!i;) 구문과 같이 장난스러운 면접 질문으로 는 활용할 수 있을 것 같다.
 
 
 

3. Annotation, Decorator

사실 데코레이터의 하위 요소로 어노테이션이 있다고 볼 수 있다. 어노테이션은 뒤에 오는 필드에 메타 데이터를 기록해 두는 일종의 마커이고, 데코레이터는 뒤에 오는 대상을 감싼 고차함수를 만드는 것이다.
 

stackoverflow에서 발견한 답변 중 하나. Typescript 측면에서의 설명이지만 뜻은 같다.

 
그렇다보니 어노테이션은 그 기능을 실행하기 위해 메타데이터가 있는 요소를 추출하고 처리하는 구문이 필요하며, 데코레이터는 반환되는 것이 새로운 함수이니 그대로 사용할 수 있다. 물론 고차함수라는 특성상 어노테이션의 동작처럼 메타데이터를 삽입할 수도 있다.
 

스프링 프레임워크는 SpringApplication.run 구문으로부터 어노테이션에 대한 분석과 처리가 진행된다
데코레이터는 함수 자체를 치환해버리는 일도 가능하다(Typescript 예시)

 
어노테이션과 데코레이터는 매직 키워드로 자주 쓰이다보니 많은 사람들이 꼭 만들어보고 싶어하는 기능 중 하나이다. 개인적으로 직접 어노테이션이나 데코레이터를 만드는 것에 대해 매우 부정적이다. 몇몇 프로젝트에서 직접 만들어보니 확장성이 뛰어나지도 않고 코드 플로우를 따라가는 것이 쉽지 않았기 때문이다. 특히 다른 개발자가 이어받았을 때 그 단점이 더욱 크게 다가온다. 초보 개발자들이 쉽게 빠지는 디자인 패턴과 같은 부류라고 볼 수 있지 않을까.
 
 
 

4. Build, Bundle, Compile, Transfile

자바스크립트는 런타임-인터프리팅 언어이다. 그렇기 때문에 기계어로 변환시켜놓는 컴파일이 필요하지 않다. 타입스크립트의 경우에는 조금 기묘한 구조를 가지는데, 소스 언어와 산출물 언어가 모두 기계어가 아닌 고차원 언어 소스 코드이기에 TS -> JS로 변환하는 과정을 트랜스파일링이라 부른다.
 
'빌드'라는 용어의 경우는 사용하기에 더욱 이상하다. 다른 컴파일 언어에서의 빌드는 소스 파일들을 컴파일하고 실행 가능하도록 요소들을 링크하는 과정을 통틀어 말한다. 하지만 자바스크립트는(클라이언트 사이드/서버 사이드 모두) 특정 컨텍스트이자 일종의 샌드박스 위에서 실행되는 것이다보니 용어 그대로의 실행 가능한 산출물을 만들어내는 빌드가 존재하지 않는다. 흔히 번들링을 빌드라고 부르고 있지만, 번들링은 종속성 그래프를 그리고 진입점(엔트리 포인트)를 찾아 파일로 만들고 사용되는 에셋을 '정리하는' 것이라고 보는게 더 나을 것 같다.
 
굳이 따지자면 '번들' 파일을 '빌드'하는게 맞지 않나 싶긴 한데... 뭐 Webpack을 위시한 프로젝트가 기본이 된 지금은 아무런 의미가 없어진 것 같다.
 

사실 웹팩 공식 홈페이지에서도 마구 섞어 칭하고 있다

 
 
 

5. js, mjs

특정 요소를 외부로 노출하여 공통화하는 모듈 시스템이 JS 진영에 들어온 이후, 그러한 모듈 시스템용 '조각' 소스 파일을 지원하기 위해 mjs라는 확장자를 사용하기 시작했다. 하지만 이미 babel이나 typescript 등을 통해 모듈 시스템을 사용하고 있어 혼란만을 가져오고 있다. 나만 이해가 안되나 싶어 검색을 해봤었는데, 영어권에선 '마이클 잭슨 스크립트' 의 약자라는 코멘트도 꽤나 보인다. 그만큼 중요하게 와닿지 않는다는 뜻일 것이다.
 
혼란스럽기 짝이 없지만 성능을 따졌을 때에는 mjs에 우호적일 필요가 있다. V8 엔진에서는 일반 스크립트 파일과 다르게 동작하는데, 간단히 추려 보자면

  • DOM에 여러번 삽입되어도 한번만 동작 (라이브러리성 요소이므로)
  • 기본적으로 defer 속성을 포함하여 동작
  • meta 정보에 대한 접근이 가능

위 세가지 정도의 특징이 눈에 띈다. 프레임워크 기반의 코드 중심으로 변한 지금이라면 프레임워크가 mjs로 빌드해주기를 기다리기만 하면 되는 일이니 굳이 신경쓸 필요는 없을 것 같다. 
 
 
 

6. '오늘'

대부분 프로그래밍 언어의 문제인데, 기본 날짜 객체(Date)에는 타임존이 포함되지 않는다. 하지만 자바스크립트에서는 특히 더 문제가 되는데, 그 대상이 클라이언트의 브라우저라는 것 때문이다. 인터넷 브라우저는 그 특성상 다양한 시간대의 사용자가 대상이 될 수 있으므로 상황에 따라 예상치 못한 문제가 발생한다. 특히 new Date와 같은 구문으로 초기화할 때 더 큰 문제가 되는데, Date는 생성자로 들어오는 값에 대한 처리가 일관되지 못하다.
 

MDN의 Date() 생성자 설명

 
이미 우리가 KST라고 생각하고 쓰고 있던 것도 UTC로 처리되고 있고, 그걸 그냥 그대로 보여주고 있어 눈치채지 못한 것일 수 있다!
 
더 무서운 것은 노드 서버의 경우이다. DB에 저장된 날짜와 노드 서버의 날짜, 그리고 stringify되어 전달되는 클라이언트로의 날짜 이 모든 것이 정확히 일치되리라는 법이 없다. 서버의 시간을 명확히 알지 못한다면 아래와 같은 일이 생길 수 있다는 것이다.
 

KST는 UTC+09니까... UTC대상 서버로 보내려면... 9시간을 빼고...

 
프로젝트가 잘 돌아가고 있다면 관심을 가지지 않는 것이 더 좋을 수도 있다. 이건 열어서는 안되는 판도라의 상자다.
 

 


이것들은 내가 다른 뜻을 알고 있긴 하니 적을 수 있었던 것이고, 제대로 알지도 못하고 섞어쓰는 이상한 것들이 더 많을 것이라고 생각한다. 위에 적었듯 고쳐야 할 정도는 아니라고 생각하지만 최소한 '내가 섞어쓰고 있구나' 정도는 인지할 필요가 있지 않을까 싶다.
각각의 단어가 생긴 데에는 분명 이유가 있을 테니...

'ETC' 카테고리의 다른 글

gRPC에 대해  (1) 2023.12.04
2023년을 보내며  (0) 2023.11.18
FE 개발 측면에서 바라본, 쓰기 좋은 Rest API  (1) 2023.03.05
'개발함정을 탈출하라'를 읽고  (0) 2023.01.22
2022년 하반기를 보내며  (0) 2023.01.07