ES2015 리팩토링 – 2. 빠레꽁(var let const)

JavaScript 는 언제나 쉽지만 또 언제나 어렵다.
이런 개념을 처음 갖게 된게 아마도 변수가 내가 생각하는데로 작동하지 않던 시점이었던 것으로 기억한다.
개념이 생기기 전에 var를 변수 선언 해도 작동이 되고 생략해도 작동이 된다는 사실에 그냥 작성하다가 어느 새
나의 코드가 전역 변수가 되어 팀원 모두가 고생을 겪고, 변수 선언을 위에다 했는데 아래에서 올라오는 등의 경우의
내 머리속의 컨셉과 다르게 동작하는 경험을 겪고 나면 정말 혼란스러워 지는데 거기다 더해 지금 이글에서 언급하게
될 스코프, 호이스팅 등을 읽고나면 정말로 쉽지 않다라는 사실을 겪게 된다.

ES2015 부터는 변수가 두가지 더 추가가 되었다. 이번엔 그 변수들을 어떻게 이해하고 언제 사용해야 할 지에 대해서 다뤄보겠다.

JavaScript 변수 var 에 대해서

var 밖에 없었으니까 JavaScript 변수 var 에 대해서라고 제목을 정하고 들어가 보자.
몇가지 특징만 짚어 보고 넘어가겠다. JavaScript 변수에 대한 조금 더 자세한 내용은 JavaScript Definite Guide 를 추천한다.

1. 변수의 var 선언이 없으면 코드의 복잡성이 증가하게 된다.

일단 코드를 살펴보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function outer(){
function inner(){
x=4;
}
inner();
console.log("outer",x);
}
//혹은 조건문 블럭으로 진행해도 결과는 같다.
function outer(){
if(true){
x=4;
}
console.log("outer",x);
}

JavaScript는 나름 중첩시킨 함수 임에도 불구하고 x는 4를 출력하게 되어 있다. var 선언을 하지 않고 작성하면 기본적으로
직전의 상위 스코프의 변수를 찾게 되어 있는데 직전에도 선언이 되어 있지 않으면 하나 더 상위를 찾아 가게 된다. 이런식으로
의도하지 않은 전역 변수를 만들어 내고는 한다.

그렇다고 해서 선언 하기 전에 마구 사용해도 되느냐 하면 그것은 또 아닌 것이 x=4 위에 사용하면 undefined 를 출력하도록
되어 있다.

2. 호이스팅에 대해서

아래 두 코드는 위의 전역 변수에 대한 개념과 변수 스코프 끌어올림(호이스팅)에 대한 개념이 섞여 있는 예제이다.
두 코드의 차이점을 한 눈에 알아 볼 수 있을까?

  • var 선언을 안 한 경우

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function outer(){
    x=3;
    function inner(){
    console.log("inner",x);
    x=4;
    }
    inner();
    console.log("outer",x);
    }
  • var 선언을 한 경우

1
2
3
4
5
6
7
8
9
function outer(){
x=3;
function inner(){
console.log("inner",x);
var x=4;
}
inner();
console.log("outer",x);
}

var 선언을 안 한 경우 경우는 ( inner =3 , outer = 4 ) 의 결과가, var 선언을 한 경우 경우는 inner는
undefined 가 outer의 경우는 3 이 떨어진다.
왜 그럴까. var 선언을 안 한 경우 경우 결국 x의 스코프는 inner 안에서 찾을 수 없어서 outer 까지 가서 찾아 보게 된다.
호이스팅이라는 어려운 말로 적혀있지만 이 “찾아보게 된다”라는 개념으로 일단 이해하고 넘어가셔도 많은 경우에는 적용이 된다.
조금 더 확실한 의미로는 변수 선언을 끌어올림이 더 적절한 풀이가 되겠지만.
이렇게 이해하고 나면 두번째의 “var 선언을 한 경우 경우”는 오히려 더 자세히 이해가 된다.
var 선언을 한 시점에서는 스코프는 해당 함수 블럭만 찾게 될 것이고 선언이 안된 체로 사용이 되었으니 말이다.

코딩 인터뷰에나 나올 만한 이 문제는 우리가 일반적으로 JavaScript를 처음 접할 때의 난해함으로 다가온다.
블럭이 스코프를 결정하지 않는다니. 기상 천외한 언어라고 볼 수 있다.
하지만 이렇게 함으로써 브라우저 상에서 사람들이 처음 HTML 스펙과 적절히 섞을 수 있도록 사용 되었고(script 태그가 여기 저기서 얼마나 많이 import 되고 있는지 생각해 보라.) 이 호이스팅과 전역변수를 활용한 팁들도 생겨나기 시작했다.

하지만 지금의 상황은 자바스크립트의 코드베이스가 예전과는 상상도 할 수 없을만큼 커져버렸다.
전역변수를 사용한다는 것은 점점 죄악시 되어가고 있고, 좋은 패턴도 아니다.

3. 비동기 함수에서의 변수 사용

아래의 코드를 살펴보면 비동기 함수의 경우는 변수가 내가 원하는 시점과 원하는 바가 다르게 나올 때가 있다는 것을 파악할 수 있다.

1
2
3
4
5
6
7
8
var numbers = [1,2,3,];
for (var i = 0; i < numbers.length; i++) {
setTimeout(function () {
console.log(numbers[i]);
}, 0);
}
//결과는 undefined가 세번 나온다.

물론 저런 코드가 프로젝트에서 사용되어질 리는 없지만 setTimeout이 아니라 AJAX 호출이라고 생각해 보자.
JavaScript가 눈에 익은 사람은 저 코드가 굉장히 당연하게 느껴지겠지만 콜백함수라던지 받아서 실행해야 하는 경우라면
코드에 대한 명확한 스펙을 알고 있더라도 실수할 수 있는 여지는 많아진다.

let, const 에 대한 오해

이해도 하기 전에 오해를 이야기 하니 무슨 이야기인가 싶을 수도 있겠으나 ES2015 의 스펙이 나오면서 let 과 const 가 어떤 전역변수와 지역변수를 해결하는 전가의 보도처럼 이야기 되는 경우가 있어서 그런것 만은 아니라는 이야기를 먼저 하고 싶다.

여전히 ES2015에도 변수를 선언하지 않고 작업을 하면 함수 스코프를 따라 체이닝 작업(찾아보게 된다)을 통해 변수에 값을 할당하게 된다. 이것은 바꿀 수도 없고 바꿔서도 안된다고 보인다.
하지만 아래 코드를 보자. 위의 var로 선언한 코드에서 let 으로만 선언했을 뿐이다.

1
2
3
4
5
6
7
8
9
function outer(){
x=3;
function inner(){
console.log("inner",x);
let x=4;
}
inner();
console.log("outer",x);
}

두가지의 결과가 다르게 나는데 var로 선언을 할 경우는 undefined 라는 값이 나오고( 에러가 아니다!)
let의 경우는 에러를 내뱉게 된다. (명시적인 에러를 뱉는 것과 undefined를 처리하는 것은 개발 차원에서 다뤄야 할 수준이 달라진다)

let은 무엇이 다를까

앞서 언급했던 선언을 하지 않고 사용을 하면 에러가 나도록 설계가 되어 있다는 점이 일단 이야기가 되어지고 두번째는 반복문 안에서 비동기 동작이 다르게 작동한다.

이 부분도 코드를 먼저 보자. 먼저 소개한 코드에서 var를 let으로 바꿨을 뿐이다.

1
2
3
4
5
6
7
var numbers = [1,2,3,];
for (let i = 0; i < numbers.length; i++) {
setTimeout(function () {
console.log(numbers[i]);
}, 0);
}

개인적으로 이 부분은 조금 더 헷갈리게 된 것 같다. 비동기의 경우 var처럼 처리 되던것을 기본으로 생각해오던 JavaScript 개발자들에게는 오히려 혼란스럽게 다가올 수 있을 것으로 보이지만 이제는 비동기 때 변수가 따로놀지 않는 상황을 let으로 작성하면 만들 수 있다는 점에서 의미가 있을 거 같다.

const는 무엇이 다를까

다른 언어와 마찬가지로 const의 경우는 다시 할당하지 않는 상수의 역할을 한다. const 의 경우는 재할당 하려고 하면 에러가 난다.
let 과 비교하면 값을 재할당 할 수 없는 것 딱 한가지 말고는 다를 바가 없다.

이제는 무조건 let, const다. 외워라.

브라우저는 지속적으로 발전하고 있고 그에 따른 성능도 올라가지만 한가지 확실한 것은 표준 스펙에 대한 성능은 언제나 일순위라는 것이다.
그 과정에서 let, const 는 기존의 var를 완전히 대체할 수 있는 뉴 스탠다드다. 현재는 var 가 아주 조금 (그것도 아주 조금) 성능적인 우위를 점하고 있지만 장기적으로 let, const 와의 성능은 거의 차이가 없어질 것으로 (오히려 더 나아질 것으로) 예상된다.

실제 진행한 것을 블로그에 포스팅한 사례도 속속 나오고 있다.

성능 비교 : https://gomugom.github.io/let-vs-var-performance-compare/

내용을 한 부분만 인용하면

불과 1년 전 var와 let의 성능비교 테스트에 대한 블로그 포스팅을 읽은 적이 있는데, 당시에는 var가 let보다 압도적으로 빠르게 연산을 수행했던 것으로 기억한다. 그 1년 사이 둘의 성능은 같아졌다. 그만큼 최적화가 이루어져왔었기 때문이다. 그렇다면 앞서 확인했던 외부스코프에 대한 접근 성능 역시 점차 최적화가 될 것이라 기대한다.

이 블로그 포스팅도 2017년 1월의 일이니 지금은 더 빨라졌을 것으로 보인다.

그리고 앞서 언급되어 있었던 부분 중의 하나인 에어비앤비의 사례에서도 보듯이 엔지니어링에서 표준을 따라 작업을 하는 것이 현재의 성능을 쫓아가는 것 보다 장기적으로 이득인 점도 간과할 수는 없다.

프로젝트 리팩토링

이제는 standup 프로젝트를 한번 들여다 보자. ( github 페이지에 접속해서 standup 검색을 하거나 아래 URL을 클릭해서 들어가 보자. )

https://github.com/ehrudxo/standup

주소를 복사해서 git clone 명령을 통해 사용하고 있는 로칼 PC에 복사한 후에 가장 마지막 작업인 day7 을 체크아웃 받아 보자.

1
$git clone https://github.com/ehrudxo/standup & cd standup & git chekcout day7

이후 editor 를 구동시킨 후에 탐색기를 열고 프로젝트에서 var를 검색해 보자. 다음 8개의 파일이 var로 이루어져 있다.

1
2
3
4
5
6
7
8
REAMDE.md
src/__tests__/CloudDao.js
src/actions/Article.js
src/config.js
src/Editor.js
src/FileUtil.js
src/FirebaseDao.js
src/Login.js

이 중 README.md 파일은 다른 파일을 설명하면서 만든 파일이므로 나머지 파일을 바꾸고 리팩토링 해 보자. 먼저 FileUtil.js를 살펴보면
storageRef 와 ulpoadTask 가 var 로 지정되어 있다. 그런데, storageRef 를 살펴보니 다른데서 사용하고 있지 않다. uploadTask만 재사용 되므로 storageRef는 삭제하고 uploadTask는 다시 값이 할당되지 않으므로 const로 변경 해보자.

이번에는 src/actions/Article.js 를 살펴 보자. 이번에는 독자들을 위해 코드 스니펫을 가지고 와서 확인해 보도록 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export function getArticles(articles){
var items = [];
articles.forEach(function(article){
var item = article.val();
item['key'] = article.key;
items.push(item);
})
if(items && items.length>0){
return{
type : ALL,
articles : items.reverse()
}
}
}

여기서 items 는 push 명령어를 통해서 지속적으로 변경이 되니까 let으로 지정을 해야 할 것 같지만 참조형은 변경이 가능하므로 const 를 사용한다.
그리고 item 도 다시 할당하지 않으므로 모두 const 로 변경한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export function getArticles(articles){
const items = [];
articles.forEach(function(article){
const item = article.val();
item['key'] = article.key;
items.push(item);
})
if(items && items.length>0){
return{
type : ALL,
articles : items.reverse()
}
}
}

이 후 나머지는 독자들이 변경해 보도록 하자.
그리고 제대로 동작하는지 확인하려면 다음의 명령어를 실행해 보자.

1
$npm install & npm start

(tech-trend) 구루들이 찾는다는 테크 트렌드 - 해커뉴스

이 글은 회사 기술 블로그에 올리고 있는 내용입니다.
회사 기술 블로그에는 이슈가 되고 있는 기술 트렌드와 개인적으로 관심있는 기술 이야기의 주제를 번갈아 가며 연재할 예정입니다. ES2015 리팩토링에 관한 이야기가 다음번 이야기가 될 거 같습니다.

필자는 SDS Agile Core Team 에서 테크리드를 담당하고 있습니다.
OSGeo에서 오픈소스 활동을 하고 있습니다. 잘 모르는 기술에 대해서 낯선 사람들과 이야기 하면서 배워 나가는 것을 좋아합니다.

기술 트렌드에 관련해서 - 2. hacker news

클리앙

한국에 Tech 커뮤니티 중에 유명한 곳으로 클리앙이라는 곳이 있다. 시대를 풍미했던 소니 PDA의 제품명을 따서 그 때 활동했던 전문가들이 만든 커뮤니티 사이트인데 왠만한 개발자나 덕질 좀 하는 사람들이라면 클리앙의 모공은 가지 않더라도 새로운 뉴스는 방문하는 것으로 알고 있다. 커뮤니티에 참여한 사람들이 가지고 오는 뉴스들이 다른 포탈 보다 좋은 점은 몇가지가 있는데 그 중에서도 취향이 비슷한 사람들이 몰린다는 것과 트렌드를 정확히 반영한다는 것. 그리고 댓글들을 통해 판단할 근거들을 파악할 수 있다는 것을 뽑을 수 있을 것이다.
클리앙

폴 그레이엄

해커뉴스는 처음 들어보았을 수도 있겠지만 IT 분야에서 일한다고 하면 폴 그레이엄이라는 사람의 이름은 많이 들어봤을 것이다. 폴 그레이엄은 투자가이면서도 SNS 상의 수퍼스타면서 “해커와 화가“라는 좋은 책을 쓴 사람이기도 하다. (한빛 미디어. 번역 임백준)
이 폴그레이엄의 Ycombinator 에서 news 서비스를 커뮤니티를 활용해서 하고 있는데 클리앙과 매우 흡사하다. 하지만 여기는 조금 더 전문적인 영역까지 다루고 있다.
폴 그레이엄

폴 그레이엄의 ~ 시리즈는 구글 검색만 해도 국내 언론도 굉장히 많이 언급하고 있음을 알 수 있다.

폴 그레이엄의

해커뉴스

이 해커뉴스가 돌아가는 방식은 좋아요를 많이 받을 수록 최상위에 배치되는 것 + 날짜 의 합으로 운영이 되는데 URL을 통해 데이타를 긁어오는 방법이 한참 유행했었는데 요즘에는 Firebase 와 함께 협업해서 API를 제공해 주는 서비스까지 제공해 주고 있다. ( 긁어가는 것도 대인배. 알아들 긁어가시는데 고생하시지 말고 알아서 긁어들 가시라고. )
해커 뉴스

해커뉴스 - https://news.ycombinator.com/

해커뉴스 API - https://github.com/HackerNews/API

굉장히 많은 사람들이 몰리는 것과 빠른 트렌드를 반영하는 것과 더불어 모든 뉴스를 다 읽기에는 하루가 모자랄 지경이라 좋은 뉴스를 선별해서 볼 수 있도록 해주는 서비스도 많은데 이 중에서 좋은 것 하나를 선택하면 최신 트렌드가 어떻게 돌아가는지를 놓치지 않고 읽어볼 수 있다.

1. hacker news twitter

트위터 서비스들

해커뉴스 트위터들

이중에서 가장 처음에 올라온 것만 개인적으로 팔로우 하고 있지만 시간이 된다면 차이점을 파악해서 잘 선택하시는 것이 도움이 될 것으로 보인다.

2. hacker news newsletter

이메일로 뉴스레터로 보내주는 서비스를 하는 것도 있다.
http://www.hackernewsletter.com/
이메일을 제출하면 해당 메일주소로 확인메일이 날라오고, 그 메일에 확인 버튼을 눌러 구독을 확정지을 수 있다.

3. Mobile apps

앱스토어나 구글 플레이에서 hacker news 라고 검색을 하면 해당 앱이 스크롤을 다 채울만큼 나오는 것을 확인할 수 있다.

영알못이라구요?

언어적인 어려움이 당연히 존재를 하는데, 이런 경우는 국내에서 트렌드 서비스를 하고 있는 몇몇 블로거들을 통해서 관련 내용들을 얻을 수 있는데, 유명한 기술 트렌드를 서비스 해주는 사람으로는 outsider 와 nolboo 가 유명하다. 국내에서 트렌드 서비스를 해 주는 경우는 다음번에 알아보도록 하겠다.

7월의 프로젝트 - Best-websites-a-programmer-should-visit

7월 7일 현재 한달동안(6/8부터) 가장 Star(좋아요)를 가장 많이 받은 프로젝트는 “Best-websites-a-programmer-should-visit” 이다.

best

작년 한해 동안은 awesome 시리즈가 유명했는데 awesome 시리즈는 예를 들어 tensorflow와 관련해서 괜찮은 사이트나 문서를 모아놓은 markdown 파일을 만들어 놓고 링크를 걸어 놓고 찾아가기 좋은 즐겨찾기를 하는 형식이다.
ex) awesome tensorflow
awesome tensorflow 만해도 8000개의 star를 받았다.

올해는 약간 네이밍에 질려하는 분위기인 것 같지만 즐겨찾기는 언제나 도움이 되니까 다들 star 버튼을 누르는게 즐겨 찾기용으로 사용되는 것을 알 수 있다.

처음 시작은 when you get stuck 섹션으로 시작한다. 한국말로 해석하면 “~을 하다가 막혔을때” 라는 것보다 더 적절한 해석이 없을 거 같은데 Stack Overflow 와 Quora 는 당연히 소개가 되어 있고 나머지 세군데는 한번 살펴 보는 것도 괜찮아 보인다.

두번째는 뉴스인데 당연히 처음부터 Hacker news 가 나온다. 관련된 사이트만도 두개가 더 있다.

bestnews

이렇게 프로젝트를 잘 정리해 놓은 사이트는 늘 깃헙의 베스트 단골 메뉴인데 적어도 한달 단위로 올라오는 트렌딩에서는 참조할 만하다. 개발자들이 꼭 참조해야할 사이트가 이렇게 많았다는 것도 놀랍지만 이제는 이런 사이트에서 공통으로 나오는 이야기들을 잘 모아서 보여주는 서비스를 한번 기획해 보는 것도 굉장히 유익해 보인다.
혹시 같이 할 사람 있다면 언제든지 연락주면 같이 해 보고 싶다.