기본 콘텐츠로 건너뛰기

GET VS POST

 어렸을 때, http를 처음 배울때, GET과 POST method를 배웠다.   해당 내용을 배울 때, GET은 URL에 파라미터를 보내게 되고, POST 소포처럼 데이터를 Body에 실어서 보내는 것으로 배웠고, 해당 내용의 차이로 GET방식은 많은양의 데이터를 보내지도 못하고, 주소창에 노출 되므로 보안상의 문제가 된다. 라는 식으로 배웠던 기억이 있다.  그때 당시에 그러면 POST만 있으면 되는 거 아닌가? 라는 생각을 하기는 했다.  위의 내용은 사용법의 차이일 뿐, 조금 다시 생각해볼 필요가 있다. GET메소드는 데이터를 조회(Read)하는 경우, POST의 경우 데이터를 변경하는 등의 Create(생성), Update(변경), Delete(삭제)하는 경우에 사용해야 한다는 내용으로 알고 있는 경우가 있다.  여러분들도 멱등성이라는 단어를 들어보았을 수도 있고, 안 들어본 개발자 또한 있을 것이다. 멱등성 은 수학에서 사용 하는 단어로 처음 들었을 때 난해한 단어긴 하다.  멱등성이란 간단히 예기하면, 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미한다. 예를들면 1*1 = 1이다 모든 수에 1을 곱하는 행위는 아무리 많이해도, 결과값이 달라지지 않는다. 0을 더하는 행위도 마찬가지이다.  즉 따라서, GET메서드는 여러번 요청한다고 하더라도 변경을 하지 않게 구현을 해야 하며(멱등성을 보장해야 한다.), POST의 경우에는 데이터를 변경할 수 있다.(비멱등성 함수이다.)  자 여기까지가 GET과 POST의 차이이다. 안전한 메서드 라는 개념이 없기 전까지는 말이다.  안전한 메서드 VS 멱등성 자 아래의 함수가 있다고 해보자.  function get(id) // Get method  function delete(id) // Delete method  function insert(data) // Post me...

이 문장은 거짓이다.

이번에 소개드릴 내용은 이상한 자바스크립트이다. 1.  배열은 배열이 아닌것과 같다. 이게 무슨 소리일까? console . log ([] == ![]) console . log (+[] == +![]) 위의 항등 연산자는 결과가 어떻게 될까? 특이하게도 위의 결과 둘다 true가 찍힌다. 항등연산자에서 빈 배열은 0으로 값이 있는 배열은 1로 형변환이 가능해진다. [] == ![] 위의 []는 0으로 형변환이 되었고, ![]는 배열을 부정을 하여 false가 되었을 거다. 진위값 또한 false는 0으로 true는 1로 형변환이 가능해진다. 그렇기에 위처럼 둘다 true가 나오는 참사(?)가 발생했다. 2.  배열도 배열이 아닌것도 진실이 아니다. console . log ( true == []) console . log ( true == ![]) 이번 문제는 1번의 해석을 잘 풀어보면 풀수 있을 것이다. 맞다. 위의 결과는 둘다 false가 나온다. 분명 둘중 하나의 경우에는 true를 뜻하고 있어야 함에도 불구하고, 서로 다른이유로 [], ![]을 항등 연상자에서 거짓으로 판별 당했다. 3. 0보다 작거나 같지않지만, 0이하인것 console . log ( null == 0 || null < 0 ) console . log ( null <= 0 )  대부분의 분들이 위의 결과를 둘다 false라고 알고 있을 것이다.  여태 배워온 몇몇 언어들이 null, N/A에 대해서 비교를 제한하고 있는 경우가 많다. 비교를 하면 무조건 거짓이 나온다는 등 말이다. 아래 링크를 보면 자세하게 알 수 있겠지만, 관계연산자 인 경우 숫자형으로 변환시키는 것이 더욱 강제적으로 수행된다고 보면 된다. https://262.ecma-international.org/5.1/#sec-11.9.3 https://262.ecma-international.org/5.1/#sec-11.8.5 즉 아래의 주석과 같이 해석 되었...

알면 쓸만한 자바스크립트 배열 함수

 1. 배열에서 중복 데이터 제거. const data = [ 'sejiwork' , 'sejinjja' , 'sejinjja' , ' 홍길동 ' , ' 홍길동 ' , ' 홍길동 ' , ' 홍길동 ' ] const uniqueData = Array . from ( new Set ( data )) console . log ( 'uniqueData' , uniqueData ) const uniqueAlpha = Array . from ( new Set ( 'sadfsdafas' )) console . log ( 'uniqueAlpha' , uniqueAlpha )  위 처럼 Set은 생성자의 인자로 iterable 객체를 받을 수 있고, 해당 데이터에서 중복이 없어지는 특징 을 같고 있고,   Array.from은 length속성과 인덱싱된 요소를 같는 유사배열객체와, map과 set처럼 순회가능한 객체를 이용하여 배열을 만들 수 있기 때문에 간단하게 두가지를 이어서 중복을 제거 할 수 있다. 2. 배열 자르기 (앞에서) const data = [ 'sejiwork' , 'sejinjja' , 'sejinjja' , ' 홍길동 ' , ' 홍길동 ' , ' 홍길동 ' , ' 홍길동 ' ] data . length = 3 console . log ( data ) 배열의 길이를 변경만 해주었을 뿐인데, 앞에서 3개만 남았다. const stringData = 'abcde' stringData . length = 2 console . log ( stringData ) 아쉽게도 문자열은 지원하지 않는다. https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Gl...

알면 쓸만한 자바스크립트 문법

 1. Nullish coalescing operator 아래와 같은 코드가 있다. function getTitle (title) { return title || 'no title' } console . log ( getTitle ( ' 알면 쓸만한 자바스크립트 문법 ' )) console . log ( getTitle ()) console . log ( getTitle ( '' )) 당연하게도 위와 같은 결과를 볼 것이다. 하지만, 마지막 console . log ( getTitle ( '' )) 타이틀이 공백문자열 일때는 제대로 표현 되지 않았다. 이럴때 쓸수 있는 것이 아래와 같은 코드이다. function getTitle (title) { return title ?? 'no title' } console . log ( getTitle ( ' 알면 쓸만한 자바스크립트 문법 ' )) console . log ( getTitle ()) console . log ( getTitle ( '' )) 위의 ?? 연산자는 null과 undefined에 대해서만 처리가 된다. 2. console 출력 꾸미기 콘솔을 보다 보면 아래와 같이 이상하게 멋있는(?) 콘솔들을 볼 수 있다. 개발자 대상으로 경고 목적이나, 개발자들한테 전달 하고 싶은 내용들을 멋있게(?) 노출 시킨 다. console . log ( "%c 콘솔을 꾸며 봅시다 ." , "color: yellow; font-style: italic; background-color: blue;padding: 2px" ) ; 위처럼 %c키워드를 이용하면, 뒤에 있는 font-style을 적용 시킬 수 있다. 브라우저별로 사용 가능한 키워드가 있으니 주의 하자. <- 뭐 물론 스타일이 적용 되지 않는다고 버그로 인식 하진 않을 테니 뭐... 3. Optional chai...

var는 왜 쓰지 말라고 할까?

 요즘에, var를 쓰지 말라는 사람들이 많아서, es6이후에 자바스크립트를 배운사람들은 처음보는 키워드일 수도 있고, 그냥 변수 선언 하는 키워드정도로 생각을 하는데, 왜 쓰지 말라는 지에 대해서 잘 모르는 분들이 있을 것이다.  아래의 코드들로 하여금 어느정도 해당 키워드의 나쁜점을 좀 드러 낼 수 있게 let과 비교를 하며 설명을 드리고자 한다.  몇가지 집고 아래 코드를 보도록 하자, 않그러면 코드 자체가 이해 안 될 수 있으니.  1. var, let은 스코프의 차이가 있다. var의 경우에는 function scope, let은 block scope를 가진다. ( function () { //... function scope { //... block scope var a = 1 console . log (a) } console . log (a) })() ( function () { //... function scope { //... block scope let b = 1 console . log (b) } console . log ( b ) // Uncaught ReferenceError: b is not defined })()  var의 경우에는 블록 스코프 내에서 선언이 되었지만, 해당 함수내에서는 참조 가능 한것을 볼 수 있다 var는 function scope를 갖는다.  let의 경우에는 블록 스코프 내에서 선언이 되었고, 블록에서 벗어 나자마자 참조 불가능 한것을 볼 수 있다 let은 block scope를 갖는다.  2. TDZ ( function () { console . log (a) // undefined var a = 1 })() ( function () { console . log (b) // Uncaught ReferenceError: Cannot access 'b' befor...

비동기 코드를 순회 하자

 들어가기 앞서, promise, async, await을 모르는 분은 아래의 링크를 먼저 읽도로 합시다. https://www.blogger.com/blog/post/edit/5763507515709642449/5970595066280268078    개발을 하다보면, 여러개의 네트워크 요청을 한번에 처리해야 하는 경우가 많다. 간단하게 아래처럼 시간이 10초 이내로 랜덤하게 걸리는 요청이 있다고 해보자. const callApi = (param) => { return new Promise (resolve => setTimeout (() => resolve(param) , Math . floor ( Math . random () * 5 ) * 1000 )) }  1. 간단하게 아래와 같은 코드로 여러번의 호출을 실행해보았다. const paramList = [ 1 , 2 , 3 , 4 , 5 ] for ( const param of paramList ) { callApi ( param ). then (res => console . log (res)) }  2. 위와 같이 정상적으로 실행이 되었다. 하지만, 결과에 대한 표시와 요청순가 달라져서 순서대로 표시가 되게 수정을 해달라고 요청이 왔다. const promises = [] for ( const param of paramList ) { promises . push ( callApi ( param )) } Promise . all ( promises ). then (resList => resList. forEach (res => console . log (res)))    3. 위와 같이 코드를 변경 하여서 모든 요청이 완료 되고나서 요청 순서대로 표시가 되게 수정을 완료 하였지만, 이번엔 백엔드 개발자 분이 오셔서 1 ~ 5번까지 순서대로 요청을 하고, 요청이 완료되면 다음 요청을 보내달라고 요...

1000만 개 중에 2개 주세요(feat. lodash)

 예전 주제로 게으른 평가를 구현해보는 주제로 포스팅 했던적이 있다. 그것 또한 lodash에 구현되어있는지 테스트 및 사용 법을 포스팅 하고자 한다. https://sejiwork.blogspot.com/2020/12/1000-2.html  그 당시의 코드를 확인해보면 아래와 같다. const calcPointList = go ( members , lazyMap ( member => { const { family , point } = member return { ...member , calPoint : family * point } } ) , lazyFilter ( ( { calPoint } ) => calPoint >= 1000 ) , lazyMap ( ( { calPoint } ) => Math . floor ( Math . sqrt ( calPoint ) ) ) , lazyFilter ( calPoint => calPoint % 2 ) , take ( 2 ) )  위에 보면, lazyMap, lazyFilter, lazyMap, lazyFiler, take를 사용 함으로써, members데이터 모두를 map, filter, map, filter, take 순회 하는 것이 아닌,  members 데이터 각각을 가지고 lazyMap, lazyFilter, lazyMap, lazyFiler, take 한번씩 돌려보고 데이터가 두개(take(2)) 되는 순간 더 이상 평가를 하지 않아도 되게 처리 되었다.  전에 테스트 했던 방식과 같이 샘플 데이터는 아래와 같은 함수로 처리 하고자 한다. const genMember = () => { return { family : Math . ceil ( Math . random () * 8 ) , point : Math . ceil ( Math . random (...

lodash 소개

 Lodash : 공식적인 소개 모듈성, 성능 및 추가 기능을 제공하는 최신 JavaScript 유틸리티 라이브러리입니다. 라고 표현 됩니다.  자주 사용 하는 함수들을 기본적으로 제공하는 ES6에서 제공하는 기본함수들과 비교를 좀 하면서 소개 드리겠습니다.  테스트에서 사용 하는 데이터는 아래와 같습니다. const bookList = [ { name : ' 재미있는 책 ' , author : 'tom' , pages : 123 } , { name : ' 재미없는 책 ' , author : 'tom' , pages : 200 } , { name : ' 그저 그런 책 ' , author : 'tom' , pages : 150 } , { name : ' 재미있는 책 ' , author : 'alice' , pages : 150 } , { name : ' 재미없는 책 ' , author : 'alice' , pages : 300 } , { name : ' 그저 그런 책 ' , author : 'alice' , pages : 450 } ]  1. filter, find   1-1. 저자가 "tom"인 책들을 찾으시오. _.filter( bookList , { author : 'tom' }) bookList . filter (({author}) => author === 'tom' )   1-2. 저자가 " alice"고 제목이 "재미있는 책"을 찾으세요. _.find( bookList , { author : 'alice' , name : ' 재미있는 책 ' }) bookList . find (({author , name}) => author === '...

Moment.js 소개 (시간에 대한 라이브러리)

 Moment는 시간을 다루기 편안한 라이브러리 입니다.  1. 여기 아주 간단한 요청이 있습니다. 현재 시간을 YYYY-MM-DD HH:mm:ss로 표현을 해달라고 합니다. 자 이걸 Date와 Moment를 비교하여 보여드리겠습니다. const current = new Date () console . log ( getFormattedDate ( current ) ) function getFormattedDate ( date ) { return ` ${date. getFullYear ()} - ${ lpad ( date. getMonth () + 1 )} - ${ lpad ( date. getDate () )} ` + ` ${ lpad ( date. getHours () )} : ${ lpad ( date. getMinutes () )} : ${ lpad ( date. getSeconds () )} ` } function lpad ( val , length = 2 , char = '0' ) { let valStr = val && val. toString () ? val. toString () : '' for ( let i = valStr. length ; i < length ; i++ ) { valStr = char + valStr } return valStr }  위 처럼 포맷팅 한번 하기 위해서 포매팅을 하기 위한 함수와, 한자리로 나오는 함수들을 강제로 두자리수로 만들어 주기위한 함수도 구현하여야 원하는 포매팅을 할 수 있기에 매우 불편하다.  Moment.js의 표현으로는 아래와 같다. moment(). format ( 'YYYY-MM-DD HH:mm:ss' )  위의 코드를  https://momentjs.com/  해당 사이트에 접근하여 디버거 창에서 실행해보면 아래와 같이 포매팅된 날짜 형식을 구할 수 있다.  2. 2015년 ...

아이콘 폰트 (icomoon 사용법)

 장난감 프로젝트를 만들다 보면, 아이콘이 필요한 경우가 있다. 간단하게 아이콘을 인터넷에서 검색하여, 이미지로 넣어두고 이미지 태그를 이용하여, 사용하는 경우가 일반적이였지만...  요즘에는 대부분 폰트를 이용하여 아이콘을 노출 한다. 나 같은 경우에도 기본적으로  https://material.io/resources/icons 를 참고하여 아이콘 폰트를 이용할 수 있도록 처리하고, 추가적으로 필요한 아이콘이고, 일상적으로 사용 되지 않는 아이콘의 경우에는  https://icomoon.io 에서 제작하여, 아이콘 폰트로 이용 하곤 한다.  그래서 이번에는 아이콘  https://icomoon.io 의 사용법을 간단히 공유하고자 한다.   들어가자 마자 위의 icoMoonApp버튼을 누르면 아래와 같은 화면이 나타난다.  icomoon에서 무료로 제공하는 아이콘들이 보이면 위에 파란색으로 표시 되어있는 집 모양 세가지를 선택한 후, 아래의 빨간색으로 표시되어있는 Generate Font를 눌러보자.  그리고 나서 바로 다운로드를 요청해보자. icomoon.zip이 다운로드가 될텐데, 압축을 해제해 보면, 아래의 폴더 및 파일들이 있다. 아래에서 중요한 것은 font 폴더와 style.css이다. demo-files fonts demo.html Read Me.txt selection.json style.css <!doctype html > <html> <head> <link rel ="stylesheet" href ="style.css" ></head> </head> <body> <span class ="icon-home" ></span> <span class ="icon-home2" ></span> <span class ="icon-hom...

this는 누구인가

 this... 객체지향 프로그래밍을 배우다 보면 객체 자기 자신을 지칭하는 키워드 이다. 즉 한번 결정 되면 객체 자기 자신만 지칭을 하고 변하지 않는데...  과연 자바스크립트에서도 그럴까? function Person (name) { this . name = name } Person . prototype . introduce = function () { console . log ( `My name is ${ this . name } ` ) }  위와 같이 적당히 객체지향 언어처럼 Person클래스를 만들고 메소드로 introduce를 추가해줬다. this.name이 어떻게 행동되는지 보시면 되겠다.    여기까지는 예상하는봐와 같이 각각을 잘 소개 하는 것을 볼수 있다.  자 상황을 바꾸어 보자 객체가 생성되고 최소 2초가 지난 후에 자기소개를 하는 코드를 만들어 보자.    코드를 보면 위와 다른 점이라고는 setTimeout을 통해서 호출 하는 것만 바뀌었지만... 둘다 이름을 잃어 버린걸로 보인다.  setTimeout에 introduce 바로 넣어 주는가와 함수를 한번 감싸서 넣어 주는 것과의 차이이다.  왜 그럴까?  첫번째 예제는 setTimeout에 sejiWork.introduce 함수 그 자체를 인자로 넘겨 주었다. 코드로 보면... setTimeout ( function () { console . log ( `My name is ${ this . name } ` ) } , 2000 )  위와 같은 코드로 볼 수 있다. 하지만 그 아래의 코드는 sejiWork객체가 introduce함수를 실행 시키는 코드이다.  즉 this는 호출자에 의해 결정 된다고 볼 수 있다.

클로저

 클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.  클로저를 어휘적 환경이 무엇인지 알아야 하는데 무엇인가? 1.  어휘적 범위 지정(Lexical scoping) function foo() { var test = 'test' function bar() { console.log(test) } bar() } foo()  예상 하였겠지만, 'test'라는 문자열이 출력이 된다. 위의 예시는  어휘적 범위 지정(lexical scoping)의 한 예이다.   중첩된 함수는 외부 범위(scope)에서 선언한 변수에도 접근할 수 있다는 것을 알 수있다. 2. 클로저 function foo () { var test = 'test' function bar () { console . log (test) } return bar } var fooOfBar = foo () fooOfBar ()  위의 코드는 어떠한가?  이것또한 예상 한것처럼 "test"문자열을 출력을 한다. 자 그렇다는 말 뜻은 foo함수가 실행 되는 동안 생성된 " test "문자열을 넣은 test변수가 foo 함수가 실행 된 이후에도 존재 한다라는 것이 된다.   자바스크립트는 함수를 리턴하고, 리턴하는 함수가 클로저를 형성하기 때문이다. 클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 3. 간단한 활용 법 function makeAdder (x) { return function (y) { return x + y } } var add5 = makeAdder ( 5 ) var add10 = makeAdder ( 10 ) console . log ( add5 ( 5 )) console . log ( add5 ( 10 )) console . log ( add10 ( 20 ))  클로저의 특성을 이용하여 위처럼 특정값에 항상 5를 더하는 함수를 만들거나 10...