기본 콘텐츠로 건너뛰기

dart 사용해보기.

  지난번에, dart를 설치 하는 방법을 알아보았다. 이번에는 좀 간단하게 사용 할 수 있는 방법을 공유함과 함께, dart의 재미있는 문법을 한 번 알아보도록 하자.  DartPad   https://dartpad.dev/  이 사이트는 웹에서 dart를 사용 해볼 수 있게 되어있다.   간단하게 위처럼 코드를 작성하여, 실행을 해볼 수도 있고, 또한 해당 함수에 대해서도 설명을 바로바로 확인 할 수 있게 되어있다. dart를 설치해서 써도 되지만, 간단하게 문법만 맛을 볼거면, 이걸로도 충분해보인다.  Cascades  이 문법은 꽤나 매력적이다. 동일한 객체를 리턴값과 상관없이 계속 이용 할 수 있게 해준다. 임시적으로 생성해야할 변수를 줄 수 있게 된다.  void main () { Rect rect = Rect() ; rect. width = 3 ; rect. height = 4 ; rect.setDouble() ; print( 'area = ${rect.getArea()} ' ) ; } class Rect { int width = 0 ; int height = 0 ; int getArea () { return width * height ; } void setDouble () { width = width * 2 ; height = height * 2 ; } }  위의 코드를 보면 적당히 읽힐 것이다. (3, 4)짜리 사각형을 만든 너비와 높이를 각각 두배를 하고, 넓이를 구하는 코드이다. 이 코드에 cascade를 적용하여, 아래와 같이 코드를 수정 해볼 수 있다. void main () { Rect rect = Rect() ..width = 3 ..height = 4 .....

dart 첫 걸음.

 요즘에 flutter 이야기가 많이 들어온다. flutter는 구글에서 만든 프레임워크이다. 플러터는 나중에 한 번 다룰 예정이지만, dart라는 언어를 사용하기 때문에, 일단 dart를 먼저 건드려보자.  설치   일단 윈도우 기준으로 설치를 해보자.    choco 커맨드를 이용해서 설치 하도록 가이드 되어있다.    일단, 초코 부터 설치해주도록 하자.  초코 설치는 powerShell(관리자 모드)을 이용 하도록 하자. Set-ExecutionPolicy Bypass -Scope Process -Force ; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 ; iex ((New-Object System.Net.WebClient).DownloadString( 'https://community.chocolatey.org/install.ps1' ))  위의 내용을 복사해서 붙여넣기 해주자. 진행이 완료 되면, choco 커맨드가 실행 되는 것을 볼 수 있다. 아래를 실행 하도록 하자. cmd를 사용 해도 되지만, 관리자 모드를 이용 해야한다. choco install dart-sdk  실행을 하면, script를 실행 할 것이냐, 물어보는데, 뭐 필요하니까 하는 거겠지 하는 마음이다.  Hello, world! 자, 거의다 왔다. dart create -t console cli  이대로 커맨드라인에, 작성해주자. 아 맞다. 환경변수에 dart가 등록 되므로 에러가 난다면, cmd혹은 powerShell을 껏다가 켜주도록 하자.  기본 설치 경로는 C:\tools\dart-sdk 이며, 필요시 환경 변수 path에는 C:\tools\dart-sdk\bin을 등록 해주도록 하...

innerText vs textContent

 HTML내의 텍스트나 텍스트를 쓰기위하여, innerText 혹은 textContent를 사용 해보았을 것이다. 아 물론 textContent는 안 써본 사람들도 있을 것이다. 아마도 innerHTML, innerText가 이름이 비슷하기도 하고, Node.textContent는 몰라도 개발하는 동안에는 큰 무리가 없을 테니 말이다.  하지만, 몰랐다면, 이번 기회에 알아 두는 것이 좋을 것이라 판단된다. 가장 큰 차이는 아래와 같다.  <html> <head> </head> <body> <div id ="test" > <span> 1 </span> <span> 2 </span> <span style =" display : none" > 3 </span> </div> <script> const test = document . getElementById ( 'test' ) console . log ( 'test.innerText: \n ' + test . innerText ) console . log ( 'test.textContent: \n ' + test . textContent ) </script> </body> </html>  자 두개의 차이를 한번 확인 해보도록 하자.  innerText의 경우에는 display:none;인 내용은 노출이 되지 않는다. 그에 비해, textContent는 display: none;을 포함할 뿐만 아니라, html 태그에 작성된, 공백까지도 노출이 된다.  자 이것이 가장 큰 차이다. 렌더링 된 레이아웃을 고려 하는가? 안하는 가? 이다.  성능  당연하게도, innertText는 렌더링 된 레이아웃을 고려하는 것은 공짜가 아니다. html이...

엑셀 데이터 불러오기 SheetJS (xlsx)

 지난번에는 데이터를 엑셀로 다운로드 받는 것을 진행 하였다. 이번에는 그것의 엑셀의 데이터를 읽어오도록 하자. 일단 엑셀데이터의 형식을 결정해보자.   위와 같은 데이터가 있다고 가정하는 것으로 시작하겠다.  엑셀 데이터 불러오기 일단 아래의 코드를 확인하자. <html> <head> <script src ="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" ></script> <script src ="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js" ></script> <script> function importExcelData (event){ const file = _. get (event , 'target.files.0' ) if (!file) { throw 'file not found' } let reader = new FileReader () reader. readAsBinaryString ( file ) reader. onload = () => { let wb try { wb = XLSX. read ( reader. result , { type : 'binary' } ) } catch ( error ) { throw error } const excelData = _. map (wb.Sheets , (sheet) => { const decodeRa...

엑셀 다운로드 SheetJS (xlsx)

  이번에 소개할 라이브러리는 SheetJS (xlsx)이다. xlsx는 npm명이고, 프로젝트 자체는 SheetJS이다. 나의 경우에, 두 개가 다른 라이브러리로 인식 했던 적이 있다.  일단, 프로버전은 사용 해보지 않았다. 웬만한 프로젝트가 기본버전으로 이용가능했고, 간단하게 일반적인 테이블의 내용을 다운로드 할 수 있는 수준이라고 보면 된다. 프로버전의 경우 차트 혹은 이미지 cell의 상세 스타일등을 지원을 해준다.  뭐 물론 csv만으로도 데이터를 다운로드 받는데에는 무리가 없을 수도 있지만, SheetJS를 사용하게 되면, 기본적으로 셀병합들은 지원 하기에, 필요하다면 SheetJS를 고려하는 것이 좋다.  준비  간단하게, 데이터를 다운로드 해보도록 하자.  준비는 아래처럼 하면 되겠다. <html> <head> <script src ="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js" ></script> <script src ="./util.js" ></script> <script type ="text/javascript" > const header = [ ' 상품 ' , ' 단가 ' , ' 갯수 ' , ' 금액 ' ] const items = [ [ ' 책 ' , 100 , 3 , 300 ] , [ ' 연필 ' , 200 , 3 , 600 ] , [ ' 공책 ' , 100 , 1 , 100 ] , [ ' 노트북 ' , 150 , 3 , 450 ] ] </script> </head...

Tagged Templates

const Title = styled.h1 ` font-size: 1.5em; text-align: center; color: palevioletred; `  혹시 이러한 코드를 본 적이 있는가? 뭐 물론 styled-component를 사용해 본 사람이라면, 이런 코드를 본 적이 많을 것이다.  하지만, 처음본 사람의 입장에서는 저런 문법이 자바스크립트에 있었나? 이 생각만 있을 것 같다. 뭐 물론, 나도 처음 저런 코드를 보았을 때, 왜 오류가 안나지? 이 생각 뿐이었으니까, 말이다.  일단 대부분이 Template literal(String template)은 많이 들어보았을 것이다. 일단 간단하게 소개 해주자면, const a = 1 const b = 2 const text = 'a: ' + a + ' \n ' + 'b: ' + b + ' \n ' + ' 합 : ' + ( a + b ) const template = `a: ${ a } b: ${ b } 합 : ${ a + b } ` console . log ( text ) console . log ( template )  위처럼 문자열을 여러줄로 표현하거나, 중간에 삽입해야 하는 값을 편하게 만들어주는 기능을 갖는다.  보면 알겠지만, ', "대신 `을 이용 하고 있다. Template literal에서 편의성을 더 제공한 것이, tagged literal이다.  간단한 사용 예제를 보여주자면, const name = 'sejiwork' const email = 'sejinjja@gmail.com' console . log ( ` 이름 : ${ name } email: ${ email } ` )  위의 정보에서 이메일 정보는 노출하고 싶지 않을 때가 있지 않나? 그러면 이러한 함수를 만들 수도 있을 것이다. const name = 'sejiwork' cons...

마이크로태스크?

 Promise를 사용하다 보면, then/catch/finally의 콜백은 비동기적으로 호출 된다는 것을 알 것이다.  아래와 같이 바로 시행 되는 코드라고 해도 말이다. window . addEventListener ( '' , () => console . log ( 'test event' )) setTimeout (() => { console . log ( 'setTimout' ) }) Promise . resolve (). then (() => console . log ( 'promise then' )) console . log ( 'end' )  일단 코드를 보니, Promise의 then과 setTimout이 같은 비동기더라도, Promise then이 먼저 호출 되는 것을 알 수 있다. 뭐 물론, 이런식으로 딴지를 걸 수 있다. setTimout과 .then이 순서가 없지만, setTimeout의 타이머를 확인하느라 실행이 늦은 걸 수 있지 않냐.  그러면 코드를 개선해서 가정을 확인해보자. console . log ( 'start' ) setTimeout (() => { console . log ( 'setTimout' ) }) const pr = Promise . resolve () pr . then (() => { pr . then (() => console . log ( 'promise then in promise then prev start' )) console . log ( 'promise then start' ) const cur = new Date () while ( new Date () - cur < 1000 ) {} console . log ( 'promise then end' ) pr . then (() => console ...

WeakMap vs Map

  WeakMap은 무엇일까? 간단하게 말하면, key를 Object로만 사용하는 Map이다. 물론 이렇게만 말한다면, Map의 하위 호환 처럼 보인다. 그렇다는 것은 이것은 무엇 때문에 생긴것일까?  WeakMap은 무엇이 약한 Map일까? 키에 대한 참조가 약한 Map이다. 키에 대한 참조가 약하다니 무슨 뜻일까?  Map은 key가 더 이상 접근이 불가능 하더라도, Map에는 값이 존재한다. 하지만 WeakMap은 가비지 컬렉션의 대상이 되어 가비지 컬렉터한테 걸리면 key를 참조 하지 못하는 데이터를 제거 한다.  예제를 보면 이와 같다. let weakmap = new WeakMap () let obj = { key : 'key' } weakmap . set ( obj , 'hello' ) console . log ( weakmap . get ( obj )) // 'hello' obj = null // obj 가 가비지 컬렉션에 의해 제거됨 // weakMap {obj, 'hello'} 또한 가비지 컬렉션에 의해 제거된다 . let map = new Map () let obj = { key : 'key' } map . set ( obj , 'hello' ) console . log ( map . get ( obj )) // 'hello' obj = null // obj 가 가비지 컬렉션에 의해 제거됨 // map {obj, 'hello'} 제거 되지 않는다 . weakmap에는 데이터가 존재 하지 않는다. map에는 여전히 데이터가 존재한다.  가비지 컬렉터가 실행 된 이후에 각각의 객체를 확인 해보면 위와 같이 확인 할 수 있다. 하지만, 가비지 컬렉터가 실행되지 않았다면, WeakMap을 이용 하더라도 아래처럼 확인이 되니, 주의하자. 접근 할 수 있는 key제거 되었지만, value가 남아있다.  참고로 위처럼 한번이라도 개발자 콘솔...