이것저것

공부하기

  • 데이터를 많이 모아 보려고 하고 있다.
  • 데이터를 모으는것은 그냥 모으면 되지만, 이것들을 어떻게 활용 할 것인가에 대한 고민...
    • 데이터를 "처리"하는 부분
    • 데이터를 "분석"하는 부분
    • 데이터를 "활용"하는 부분
  • 으로 나뉘어 질텐데, 우선 텍스트를 쉽게 분석? 할 수 있는 엘라스틱 스택에 대해서 공부 하기로.

읽기

  • 우선 이 책은 초보자를 위한 책은 아님이 확실하다.
  • 엘라스틱 서치의 많은 것을 알려 주기는 하지만, 설명이 장황하고, 구체적이다. 초보가 보기에는 정보가 너무 많아, 너무 어렵게 느껴 질 것으로 판단된다.
  • 이 글에서는, 책의 순서가 뒤죽 박죽이 될 수도 있겠다.

02장 일래스틱서치 시작하기

  • ubuntu 에서 apt로 elasticsearch를 설치하면, 9200 포트에 접근이 되지 않는 경우가 있다.

    • /etc/elasticsearch/elasticsearch.yml 파일에서 network.host 부분을 0.0.0.0으로 변경해 준다.
  • p57 kibana에서 REST API 호출하기

    • GET /라고 입력한 뒤, 초록색 삼각형()을 누르면 해당 쿼리가 실행된다고 한다.
    • 더 쉬운 방법이 있다. 실행하고 싶은 쿼리가 있는 곳으로 커서을 옮긴 뒤, Ctrl + Enter를 입력하면, 커서가 있는 위치의 명령이 수행된다. 이걸 쓰도록 하자.
    • kibana Dev Tools 에서 쿼리를 입력하는 도중 문제가 있으면, 에러 표시()를 해 주므로, 쉽게 사용할 수 있다.
      • 아래는 json의 key 부분인 params"로 감싸지 않아서, 문제가 있다고 알려줌.
      • 단, 모든 에러를 모두 찾아주는건 아니니깐.. 그건 어쩔 수 없음. ㅋ.
  • 엘라스틱 서치에서 REST API의 동작이 ... 뭔가 .. 좀 이해하기 어렵다.

    • 보통 POST는 "추가/생성"의 의미를 가지고, PUT은 "수정(혹은 생성?)"의 의미를 가지는데, 이책의 예제들을 보면, 그게 좀 모호하다.
      • POST
        • id 지정 없이 데이터를 추가하고 싶은 경우(서버가 알아서 id를 할당)
        • id 가 있고, 데이터를 수정하고 싶은 경우 (응???)
      • PUT
        • 인덱스를 새로 만들고 싶은 경우
        • id를 지정해서 도큐먼트(데이터)를 추가하고 싶은 경우
  • p60 가운데 그림

    • 노드 이라고 되어 있는데, 아마도 인덱스가 되어야 할 것이다.
    • 실제 노드에 대한 설명은 64, 64 페이지에 나온다.
  • p78 가운데 업데이트 API 예제

    • POST /catalog/product/1/_update { 에서 마지막 {를 빼야 한다.
    • 다음줄에 {가 또 나오기 때문이다.
    • Kibana에서 입력할 때도 _update뒤에 {가 있으면, 아래와 같이 에러가 발생한다.
  • p 82 인덱스의 매핑을 지정하기 위해서 mappings를 사용하는 부분.

    • mappings로 되어 있어서, 여러개의 type을 넣어 보고 싶어서 시도 했으나, 한개의 인덱스에 여러개의 type을 넣으니 에러가 발생했다. 이상하다, 분명히 인터넷에 여러개의 type을 넣는 예제( [Elasticsearch] Multi types into Index. )도 있는데 말이다.

    • 근데 왜 mappings일까?

      • 한국 엘라스틱에서 올린 글( 미처 못 다한 이야기들 - Elastic{ON} Tour Seoul )에서 이유를 찾을 수 있다.

        • 타입(Type) : 엘라스틱 서치 6.0부터는 타입이 하나로 제한됩니다. 단, 5.x에서 만들어진 인덱스는 6.0으로 업그레이드 했을 때도 그대로 여러 타입을 사용할 수 있습니다.

      • 즉, 이전에는 mappings가 정확한 의미를 잘 표현한 것이고, 6.x에서 달라졌으나, 그 이름을 그대로 활용하는 상태라고 이해된다. 그냥 mapping이라고 하나 추가해도 될 듯 한데...

  • p83 기존 인덱스에 타입 매핑 생성

    • 인덱스를 생성한 후에도 인덱스 타입을 추가할 수 있다.라는 말이 있는데, 이게 상황에 따라 다르다.

    • 이전 페이지인 p 82 에서 이미 catalog에 대해서 my_type이라는 타입을 만들어 두었다.

    • 위에 설명한 mappings에 대한 설명을 적용하면, 한개의 인덱스에서는 두개의 타입을 넣을 수 없다. 그러므로 이미 my_type이라는 타입을 넣어 두었으므로, p 83에서 추가하려고하는 catalog 타입을 넣으려고 하면, 아래와 같이 에러가 발생한다.

    • 그러므로, 정확한 설명은 인덱스를 생성하고, 타입을 추가하지 않은 경우, 나중에 타입을 추가할 수 있다. 라고 되어야 한다. 이를 모두 자세히 나열하면 아래와 같은 것이다.

      • DELETE /catalog로 먼저 생성해둔 catalog 인덱스를 삭제
      • PUT /catalog인덱스만 생성
      • PUT /catalog/_mapping/category { ... }category 라는 타입을 추가하면서 mappings까지 설정
      • GET /catalog/_mapping/을 통해서 category라는 타입mappings가 잘 설정 되었는지 확인.
    • 일반적으로 mapping을 만들때, 전문검색(full text search)할 대상의 typetext 로 주게 된다. 예를들면 뉴스의 내용은 전문검색이 필요하므로 typetext로 설정할 것이다.

      • 뉴스에 나오는 용어를 찾기 위해서는 contents의 역색인 정보를 뒤져야 하는데, 이걸 그냥 뒤져 볼 수 있는 방법이 없다.
      • vectorterms 인가 하는 방식을 쓸 수 있는데, 그건 id가 지정된 경우에만 사용할 수 있다.
      • mapping을 생성할때, field에 "fielddata" : true를 주게 되면, 역색인 정보를 바로 검색해서 볼 수 있다.
      • 역색인 정보를 검색하려면 아래와 같이 호출하면 된다.
  • p88 JSON 응답 형식 부분

    • 기본적으로 모든 요청에 대한 응답은 형식이 없다. .. 어떠한 형식도 지정되지 않는다. 부분의 번역이 언뜻 이해하기 어렵다.
    • 단 한줄로 json응답이 오면 응답 형식이 없는 상태이고, 엔터와 탭으로, 예쁘게 json 응답이 오는것을 응답 형식이 있는 상태라고 해석하고 있다.
    • 아마도, "포맷(format)"을 "형식"이라고 번역했지 않을까 생각해 본다.
    • 기술 서적이라면(적어도, 이정도의 고난이도?? 기술을 다루는 책이라면.. 모든것을 번역할 필요가 있을지 의문이다... )
    • 책에서는 ?pretty=true를 사용했지만, 단순히 ?pretty만 사용해도 json 형태의 응답이 예쁘게 출력 된다.
    • 또한 JSON 형식 뿐만 아니라, yaml 형태로 출력 할 수도 있다. ?format=yaml를 이용해서 쿼리를 날리면 된다.
  • p90 GET /_search의 결과물 부분

    • 책에서는 나오지 않지만, 실제로 쿼리를 실행하면, 우리가 만든 category 뿐만 아니라, 우리가 만들지 않은 .kibana_1이라는 인덱스를 발견할 수 있다.
    • 이건 말 그대로 kibana용 인덱스이다. 언제 이런게 만들어졌나고?
    • kibana를 최초로 실행시키면 아래의 로그를 볼 수 있다.

03장 유사도 검색

  • 이후 부터 용어라는 말이 나오는데, 영어로는 term이다. ( 사실 이미 p73 등에서 등장한 말이다.) 역색인시 사용하는 key 정도로 이해하고 우선 넘어 가면 될 듯 하다. ( key일래스틱 서치와 같이, 여러개의 단어로 이루어져 있을 수도 있을것 같다. - 정확하지 않음.)

  • p94 전문검색 이라는 용어가 나오는데, 全文검색이다. 영어로는 Full Text Search

  • 텍스트 분석기는 아래의 3가지 과정은 순차적으로 거친다

    1. 문자 필터(Character filters) : 0개 이상 - 문자열 치환 등 문자열 처리
    2. 토크나이저(Tokenizer) : 정확히 1개 - 문자열을 쪼개주는 역할, 역색인 만들때 사용
    3. 토큰 필터(Token filters) : 0개 이상 - 쪼개진 문자열을 다시 처리하는 역할, 각 토큰으로 들어온 문자열을 소문자로 바꾸거나, 불용어(The, a, an, is ...)를 없애주는 등의 처리 가능
  • 토크나이저(Tokenizer)는 문자열을 잘라주는 역할인데, 표준분석기, 언어분석기, 공백분석기 등이 있다.

  • 이 중에서 제일 재미난건 언어 분석기인데, 사실상 이 놈의 핵심인것 같다.

  • 재수좋게도, 2018년 8월 24일에 엘라스틱에서 공식 한국어 분석 플러그인 '노리'를 만들었다. 아싸!!

    • 용량이 작다.
    • 속도가 빠르다.
    • 공식지원이니 설치가 편하다.
  • 설치하는 방법과 간단한 사용방법은 Elasticsearch 6.4 기본 한글 형태소 분석기 노리 (nori) 설명 및 사전 추가하기를 방문해서 확인해 보자.

  • REST api로는 아래와 같이 호출해 보면, 아래와 같이 주요 단어를 잘 뽑아 주는것을 확인해 볼 수 있다.

  • 뉴스 관련 데이터로 몇가지 테스트를 해 보았다.

    • 뉴스의 카테고리는 category라는 이름으로 그냥 text로 만들었고, title과 contents는 "nori" 분석기를 달도록 설정했다.

    • 이후 news/article type에 30여개의 document를 추가 했다.

    • 뉴스 데이터 category에 "경제"를 넣어 두고, 검색할때 "category" : "경제" 를 검색하면 아래와 같이 잘 찾아 진다.

    • 하지만 "category" : "경제적"을 검색하면 제대로 찾아 지지 않는다.

    • 이제 contents에도 똑같이 경제를 검색해 보자. "경제"라는 글자가 contents에 있는 경우에는 당연히 잘 검색 된다.

    • 이제 contents에 경제적을 검색해 보자. "nori" 분석기가 잘 동작했다면, "경제적"이라는 전체 단어가 아니라, "경제"라는 단어만 있어도 잘 검색해 줄 것이다. 아래 결과를 보면 "경제"가 들어간 결과 뿐만 아니라, 경제를도 잘 검색 된다는것을 알 수 있다. 즉, 분석기가 글자를 잘 분석해서 역색인 했다는것을 알 수 있다.

      • 구조화된 데이터 검색

  • 반면, 비슷것을 찾아주는게 아니라 정확하게 색인 된 것만 찾으려면 term 을 사용해서 찾으면 된다.

    • match를 사용하는 위의 예제에서는 경제적을 검색어로 써도 경제를 찾거나, 경제를을 찾아준다.하지만 정확하게 색인된 것만 찾으려면 term을 사용하자
    • term을 사용해서 경제적을 찾으며 아무것도 찾아지지 않는다는것을 알 수 있다.
    • 그렇다면 contents에 실제로 있는 경제를이라는 검색어를 term을 사용해서 검색하면 어떻게 될까? 아래와 같이 검색 되지 않는다.
    • term색인된 것만을 검색한다. nori 분석기에서는 경제를을 색인한것이 아니라, 경제만 색인 했기 때문에 term을 사용했을때 경제를이라는 검색어로는 찾아지지 않는것으로 보인다.
    • term을 사용하여 경제를 찾으면 제대로 찾아 지는것을 알 수 있다.
  • title이나 contents 필드는 text 타입으로 설정해 두었다. 그러므로 match로 검색을 하면 nori 분석기를 통해서 비슷한 것도 찾아 준다. 하지만 만약 category 필드와 같이 keyword 타입으로 설정해 두었다면, nori 분석기등을 통하지 않고 "정확한 것"만 검색하도록 된다.

    전문 텍스트 검색

  • match검색시 검색어에 오타가 있을 경우를 대비한 fuzziness값을 줄 수도 있다.

    • fuzziness에 1, 2 등의 값을 주면, 몇 글자가 틀려도 알아서 찾아 준다.
    • 예를 들어 경조라고 잘못 검색어를 입력해도,공조, 경찰, 경제등을 찾아 준다.
  • 반면 match에는 여러 검색어에 정확하게 맞는 쿼리를 보내고 싶을 때는 match_phrase를 사용한다. 구글에서 " " 로 감싸서 쿼리하는것과 비슷하다.

    • 단, 검색어에서 순서는 정확하게 맞지만, 일부 단어가 생략되는것을 허용하려면 slop 값을 조정하면 된다.
  • 그외 이것 저것은 생략. 나중에 필요할 때 찾아 보자

04장 일래스틱서치 분석 ( 아직 안 읽음 )

  • 아직 안 읽음.

아!! 짜증난다!!!

요 몇일 집에서 OpenCV와 nodejs(typescript)를 이용해서 이것저것 해 보고 있다. 근데... 분명 어제 만들었던 코드가 오늘은 안 돌아 갔다. 그래서 typescript로 만들어 두었던, class와 호출되는 함수를 모두 풀어서 1개의 함수로 작성했더니 잘 된다... -_-

아아! 도대체 뭐가 문제일까?

뭐가 문제일까?

1개의 함수로 풀어 두었던 코드들과 기존의 코드를 비교 했지만, 알 수 없는 이 문제... 도대체 뭐가 문제일까? 결과적으로 문제는 async와 await를 잘못 사용한 것이었다.

문제 해결

내가 만든 코드는 아래와 같다.

////////// 함수 정의
public init():void {
  //...
}
public async captureDetectFace(dir:string, maxCounter:number):Promise<FaceAddResult> {
  //...
}
public destroy():void { 
  //... 
}

/////////// 함수 호출
let fr:FaceRecog = new FaceRecog();
fr.init();
fr.captureDetectFace("..", 10);
fr.destory();

함수 중에 caputreDetectFace 함수는 async 함수로 만들어 두었는데, 함수를 호출 할 때는 생각도 없이 그냥 fr.captureDetectFace("..", 10)의 형태로 호출을 했다. 그렇기 때문에, 해당 함수의 결과(Promise)를 대기하지 않고, 바로 fr.destory()를 호출하게 된다.

fr 인스턴스가 destory 되어버렸기 때문에, fr.captureDetectFace()함수 안에서 fr 인스턴스를 사용하려고 할 때 문제가 되는 것이었다.

고치는 방법은 너무나 간단하다. fr.captureDetectFace("..",10)으로 호출할게 아니라, await fr.captureDetectFace("..",10) 처럼 await를 붙여 주면 해결 되는 문제 였다.

아! 멍청이!

기껏 코드를 다 작성하고, 문제를 찾지 못하고 있었는데... 참... javascript의 세계는 참 어렵다. 개념부터 다르니.

왜 이글을 적냐면...

그냥 적어두는 과정을 거치면, 더 잘 기억할 것 같아서 적어둔다. ㅋ.

그럼 안녕. ㅋ.

책 읽기

이것저것

  • 책의 내용을 시작하기 전에 이것저것 설명이 나오는데 이 중에서 웹 퍼블리셔라는 용어가 나온다.
    • Q. 저는 웹 퍼플리셔로 일하고 있는데 프런트 엔드 개발자로 커리어를 전향하고 싶어요. 이 책이 도움이 될까요?
    • 프런트 엔드 개발자는 뭔 줄 알겠는데, 웹 퍼플리셔라는 용어를 처음 들어봐서 정리.
    • 웹 퍼블리셔에 대한 설명은 웹 퍼블리셔의 역할 - 프론트 앤드 개발자와 차이점를 방문해서 확인해 보면 쉽게 그림으로 되어 있다.
    • 간단히 정리하면, 예전에 디자이너가 그림을 그리고, 개발자가 코딩을 해야 할 때 중간에 HTML화(?) 시키는 영역이 발전했다고 보면 된다고 한다.
    • 최초에는 HTML화 시키는 일만 했겠지만, 지금은 웹 접근성등을 지켜야 하기 때문에 더 많은 고려를 해야 하는 영역이 되었다고 한다.
    • 하지만 웹퍼블리셔를 돌아보다라는 글을 확인해 보면, 웹 퍼블리셔가 프론트엔드 개발자와 비슷한 개념으로 혼용되고 있는듯 하기도 하다.
    • 뭐.. 암튼 그럼. ㅋ.

읽으면서 정리하기

Vue.js 필수 기술 살펴보기

Vue.js 소개

Vue.js란 무엇인가?

Vue.js의 특징

  • 20페이지 아래쪽 화면 요소를 꾸미는 HTML, CSS 코드와 데이터베이스에서 데이터를 가져와 제어하는 Java 코드가 한 파일에 섞이면서 가독성이 현저하게 떨어졌습니다. 라는 말
    • 이 문장에서 Java는 꼭, Java만들 뜻하는게 아니라, 서버사이드의 코드를 뜻하는것이라고 생각하는게 맞는것 같다. Java나 PHP 등 웹 서버쪽 코드 라고 하는게 더 좋을듯 하다.

개발 환결 설정 및 첫 번째 프로젝트

뷰 학습을 위한 개발 환경 설정하기

Hello Vue.js! 프로젝트 만들기

  • 37 페이지 중간, 뷰 개발자 도구쪽에서 아래와 같이 '파일 URL에 대한 엑세스 허용' 체크 박스에 체크합니다. 라는게 있는데, 요즘에 크롬이 업데이트 되어서 화면이 좀 다르다.
  • 아래의 그림을 참고하여 켜 주면 된다.
  • 옵션을 키고나면 아래와 같이 Toolbar에 Vue 아이콘이 활성화 되고, 개발자 도구 영역에 Vue 라는게 생긴다. 그리고 Vue의 데이터 상태 같은 것도 확인할 수 있다.

화면을 개발하기 위한 필수 단위 - 인스턴스 & 컴포넌트

뷰 인스턴스

  • 46 페이지 마지막 단락 부분에 만약 여기에 값을 변경하는 로직을 넣더라도 화면이 다시 그려지지는 않습니다. 라는 말
    • 이 말을 이해하는데 오래 걸렸다.
    • 여기서 설명하는 부분은 beforeUpdate 이벤트(?) 이다.
    • 원래 일반적인 동작에서는 값을 변경하면 화면을 새로 그려야 한다.
    • 이 시점은 아직 새로 그리기 직전이니, 원래 그릴려고 하는 값을 강제로 변경하는 코드를 넣는다고 하더라도, 바뀐 값을 이용해 1번만 그린다. 즉, 원래 값을 강제로 바꾸었다고 해도, 다시 그릴려고 시도하지는 않는다. 는 의미로 받아들이면 될 듯 하다.
    • 책을 읽을때도 좀 이해하기 어려웠는데, 이걸 글로 표현하려고 하니... 어렵네? ㅋ
    • 음... 좀 이상하다. 실제로 beforeUpdate에서 message 값을 변경해 보면, 무한루프 에러가 발생한다. ;; 음.. 아직 뭔 말인지 이해가 잘 되지 않는다. ;;;
    • 여기에서 설명하는 그려지지 않습니다.라는 말은, 가상 DOM에 node를 추가하는것인지, Real DOM에 node를 추가하는것인지 모르겠다. ;;; 암튼 그려준다라는 말의 용어가 좀 더 명확해야 할 듯 하다. 뒤의 내용을 차츰 읽어 가면서, 추후 이 내용에 대한 업데이트를 하겠다.

뷰 컴포넌트

뷰 컴포넌트 통신

상용 웹 앱을 개발하기 위한 필수 기술들 - 라우터 & HTTP 통신

뷰 라우터

뷰 HTTP 통신

화면을 개발하기 위한 기본 지식과 팁 - 템플릿 & 프로젝트 구성

뷰 템플릿

  • 102 페이지 둘째, 복잡한 연산은 인스턴스 안에서 처리하고 화면에는 간단한 연산 결과만 표시해야 합니다. 라는 부분.
    • 간단한 연산 결과만 표시하는것을 권장합니다.라고 읽는게 좋다.
    • 안되는게 아니고, 권장하는것이기 때문에 결과만 표시해야 합니다.라는 말이 정확하지 않다.
    • 물론 그 다음 페이지인 103페이지 두번째 단락에서는 뷰에서 이러한 방식을 권하는 이유는 이라고 설명이 적혀 있긴 하다.

뷰 프로젝트 구성 방법

Vue.js 실전 투입!

실전 애플리케이션 만들기

할 일 관리 앱 살펴보기

프로젝트 생성하고 구조 확인하기

컴포넌트 생성하고 등록하기

  • 137 페이지의 중간 부분에 보면, components를 등록하는 부분이 있다.
    • 그런데 그것만 코드를 넣으면 에러가 난다.
    • 그 페이지 제일 마지막에 있는 import 관련 코드도 같이 적어야 한다.
    • 이 책의 설명이 좋긴 한데, 한 개의 코드 덩어리에서 설명해야 하는 부분을, 두개 이상의 덩어리로 나눠서 설명하는 경우가 있다. 이런 부분이 책을 좀 읽기 어렵게 만드는 경향이 있다.

컴포넌트 내용 구현하기

  • 151 페이지의 아래쪽 예제에서 <li v-for='todoItem in todoItems'>{{ todoItem }}</li> 부분
    • vue 2.2.0 이상에서는 v-bind:key필수로 있어야 한다.
    • 그러므로 vue 2.2.0 이상을 쓰면 아래와 같이 코드를 바꿔야 한다.
    • <li v-for='todoItem in todoItems' v-bind:key='todoItem'>{{ todoItem }}</li>

기존 애플리케이션 구조의 문제점 해결하기

더 나은 사용자 경험을 위한 기능 추가하기

  • 페이지 171의 중간에 있는 :key 속성은 v-for 디렉티브를 사용할 때 지정하는 게 좋습니다. 부분
    • 이미 바로 위인 151 페이지의 내용에 대한 설명에 적어 두었다. vue 2.2.0 이상에서는 :key속성은 필수이다.

Vue.js 고급 개발자 되기

뷰 중.고급 레벨로 올라가기 위한 지식

뷰 개발을 위한 웹팩

뷰 개발을 위한 ES6

뷰 CLI에서 사용하는 NPM

지금 당장 실무에서 써 먹는 Vue.js

뷰와 제이쿼리를 같이 사용해도 되나요?

개발 기간이 너무 짧은데 기존 레거시 고드에 어떻게 뷰를 바로 적용하죠?

뷰에 UI 라이브러리와 차트를 어떻게 연동할까요?

뷰로 프로그레시브 웹 앱을 개발하려면 어떻게 시작해야 하죠?

Vue.js

공부하기...

  • Vue.js 를 공부 해 보려고 책을 구매 했는데.. 아직 도착 안했다.
  • 그럴줄 알고, 온라인에 한글로 되어 있는 Vue.js 가이드 문서를 출력했다.
  • 링크 : https://kr.vuejs.org/v2/guide/installation.html

읽기

설치방법

시작하기

시작하기

  • <script src="https://cdn.jsdelivr.net/npm/vue"></script>를 보면, 주소의 끝이 vue로만 끝나고 'js' 확장자가 붙지 않는데, 실제로 다운로드 받아 보면 javascript 파일이 다운로드 된다.
    • 심지어 response header에서도 javascript가 전달 된다고 정보가 온다.
  • 영어 문서를 보면, 아래의 내용이 더 있다. 한국어 문서에는 빠져 있는 내용이다. 개발할때는 아래 코드를 쓰는것이 도움이 될 거란다.

    <!-- development version, includes helpful console warnings -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    

선언적 렌더링

  • 텍스트 보간 이외에도 다음과 같은 엘리먼트 속성을 바인딩 할 수 있습니다.를 보면 보간이라는게 나온다.

    • 여기서 나오는 보간은 영어로는 interpolation이다. 텍스트 끼워넣어 교체하기 이외에도 다음과 같은 엘리먼트 속성을 바인딩 할 수 있습니다. 정도로 읽으면 될 거다.

컴포넌트를 사용한 작성방법

  • v-bind:key="item.id" 부분이 있다.

    • 그 직전의 코드는 v-bind:todo="item"인데, 이 코드의 뜻은 item의 값(속성)을 Component안에서 todo라는 이름으로 사용할 것이라는거다.
    • 그렇다면 v-bind:key="item.id"라는 코드는 item.id를 Component안에서 key라는 이름으로 사용할 것이라고 예상이 된다. 하지만 실제로 key를 출력해 보면 제대로 출력 되지 않는다.
    • v-bind:key는 특별한 의미를 가지고 있기 때문에 원하는대로 처리 되지 않는 듯 하다.
    • 자세한건 뒤에 내용을 보면서 추후 업데이트 하겠다.

Vue 인스턴스

속성과 메소드

  • 유념할 점은, data에 있는 속성들은 인스턴스가 생성될때 존재한 것들만 반응형이라는것입니다. 라는 부분
    • 말그대로 Vue 객체를 생성하는 시점에 mapping 된 sturcture에 존재하는 속성들만 연동된다는 말이다.
    • 추후에 data에 속성을 추가해도, 그 값은 연동되지 않는다.
    • 근데, 그 다음 내용을 보면 $data라는 특별한 속성에 대해서 이야기가 나온다.
    • 생각해 보면 Vue 컴포넌트 내부에서 $data의 값을 이용해 연동 시킨다고 생각할 수도 있다. 하지만 주의해야 한다.
    • Vue 객체를 생성할때 mapping된 structure가 $data로 매핑되는것이다. 그렇기 때문에 vm.$data.b = 3와 같이 값을 넣는다고 해도, 추후에 컴포넌트는 만든 이후에 설정된 속성이므로 "연동"되지 않는다.
    • 그러므로 책에서 설명하듯이, 나중에 사용하려고 하는 속성들은 미리 data 의 속성으로 추가해 두어야 한다.
    • 만약 뒤늦게 반응형 속성을 추가하고 싶다면 '객체 변경 감지에 관한 주의사항' 부분을 읽어 보면 Vue.set(...)를 사용할 수 있다는것을 알려 준다.

인스턴스 라이프사이클 훅

  • options 속성이나 콜백에 ... 와 같은 화살표 함수 사용을 지양하기 바랍니다. 부분
    • 화살표를 이용한 함수사용시 this 에 대해서 다르게 동작할 수 있다.
    • 일반적인 function() 정의 안에서 this를 사용하면, 해당 function이 호출되는 Context(부모객체?)의 this를 따라가게 된다.
    • 하지만 () => { } 형태 안에서 this를 사용하게 되면, 해당 function을 정의한 Context(부모객체?)의 this를 따라가게 된다.
    • 위 말이 뭔 말인지 잘 모르겠으면 화살표 함수의 링크를 방문하여 읽어보면 된다. 자바스크립트에 대해서 잘 모른다면, 꼭 읽어 보는것이 좋다.

템플릿 문법

보간법(Interpolation)

  • 위에서 이야기 했듯이, "끼워 넣어 바꾸기" 정도로 해석하면 된다.
  • v-once 디렉티브를 사용하여 데이터 변경시 업데이트 되지 않는 일회성 보간을 수행할 수 있지만, 같은 노드의 바인딩에도 영향을 미친다는 점을 유의해야 합니다. 부분
    • 말 그대로, "v-once"로 설정된 tag 하위들은, {{msg}} 의 부분도 업데이트 되지 않는다는 말이다.
    • 한번 출력(?)되고 나면 app.msg="ccc"와 같이 값을 바꾼다고 해도, 업데이트 되지 않는다.
  • 실제로 Vue.js는 모든 데이터 바인딩 내에서 JavaScript 표현식의 모든 기능을 지원합니다. 부분
    • 쉽게 말하면 {{ msg }} 부분이나 v-bind:disabled="isButtonDisabled" 부분이나, v-bind:id="'list-'+id" 부분이나, v-if='seen', v-bind:href='url' 등 부분에서 값을 넣어 주는 '' 부분의 코드가 실행 되거나, 그 값이 할당 된다고 보면 된다.
      • 예 1 : v-if='seen'라는 코드가 있을때, seen이라는 변수의 값이 false 면, 해당 tag가 실제로 렌더링 되지 않는다.
      • 예 2 : <a v-bind:href='url'>라는 코드가 있을때, url이라는 변수의 값이 href에 할당 되는것으로 생각하면 된다. 예를 들면 <a href="http://naver.com"> 과 같이 변경 될 것이다.

계산된 속성과 감시자

계산된 속성

  • 하지만 차이점은 계산된 속성은 종속성에 따라 캐시된다는 것 입니다. 부분
    • 캐시되는 정보는 return value 이다.
    • 즉 해당 함수에서 console.log(..)를 출력한 뒤, return 'aa'라고 정의를 하면, 최초 값을 사용할 때는 console.log(..)가 출력 되지만, 그 이후 다시 해당 값을 사용하면 log가 출력되지 않는다.
    • 하지만 return value를 만들때, 변수를 사용한다면, 현재의 변수 값을 이용해서 반환된다. 변수 값이 바뀌면, return value 역시 바뀐다는것을 주의해야 한다.

폼 입력 바인딩

기본 사용법

  • 체크박스 설명중에 <label for="checkbox" ...> 부분에 대한 설명

    • 해당 label이 어느 tag와 연관이 있는지 연결해 주는 것이라고 생각하면 된다.
    • 지금은 for="checkbox" 라고 했으므로, 지금 HTML에서 id가 checkbox인 아이와 연관 되는 label이라는 뜻이다. type이 아니라 id가 checkbox인것과 연동된다는거다.
    • 이렇게 해 두면, <input> 위치가 아니라, <label>위치를 클릭해도, <input>을 누른것 처럼 동작하게 연결 할 수 있다.

      수식어

  • .lazy 설명 중에 .lazy 수식어를 추가하여 change 이벤트 이후에 동기화 할 수 있습니다. 라는 말.

    • v-model은 input text의 값이 변경되면 실시간으로 model 의 값도 같이 변경되도록 되어 있다.
    • change 이벤트는 input text에 값을 입력하는 도중이 아닌, 입력후 다른 곳으로 focus를 옮긴 이후나, 엔터를 입력하는 등의 상황에 발생한다.
    • 그러므로 말 그대로 실시간으로 적용하고 싶지 않은 경우에만 사용하면 된다.

이후 내용들...

  • 가이드 문서만 읽기에는 너무 어렵다. 
  • 소스들이 등장하기는 하는데, 전체의 소스가 아니라 소스 일부만을 설명이 나오는경우가 있어, 명확하게 파악하기 어려운 경우가 있다. 이후 중요하거나 이해를 꼭 해야 하는 부분만 정리 하도록 한다.
  • 나머지는 Do It! Vue.js 입문 책을 구매 했으니, 그 책에서 다시 정리 하던지 하자.



[도서]Do it! Node.js 프로그래밍

정재곤 저
이지스퍼블리싱 | 2017년 03월

내용     편집/구성     구매하기

책 읽기

  • 책 자체는 크기도 크고 두껍기도 하다. 하지만 안의 글자 크기가 작아서 많은 양의 정보가 담겨 있다. 아마도 책을 좀 작게 만들었거나, 읽기 쉽도록 글자를 좀 크게 했으면, 소위 "바이블"이라고 불리는 책 두께가 되었을듯...
  • 책 초반에는 아주 작은 정보까지 책에 나오고는 있으나, 그 작은 정보들을 아주 간단한 설명으로 퉁쳐 버리거나 설명하지 않은 부분에 대해서도 많은 단어들을 등장 시킨다.
    • 예를 들면 18 페이지의 작은 "주의" 박스에서는 "세션"이나 "쿠기"등의 단어를 사용하는데. 여기에 대한 설명은 없다. 그 전에는 "용어"칸을 통해서 조금 어렵다고 생각되는 단어들을 모두 설명하고 있는데 말이다.
    • 초보자들을 위한 책이라서, 세세한 설명이 달려 있는거 치고는, 설명이 부족하다. 그렇다고 설명이 안 달려 있는것도 아니니.
    • 만약 초보자가 해당 책을 읽는다면, 잘 모르는 단어가 나왔을때는 그냥 과감히 무시하고 넘어 가는것이 좋겠다. 설명 자체는 세세하게 잘 되어 있으니, 모르는 단어들은 아마도 책 뒷 부분에 설명이 나올듯 하다.

이것저것

읽으면서 정리하기

31페이지

  • 31페이지에 보면, 이런 문제를 해결하기 위해서 만든게 노드입니다라는 말이 있는데, 이 설명은 좀 이상하다고 생각된다. 노드의 특성이 비동기 입출력이지, 비동기 입출력을 위해서 노드를 만들었다고 적혀 있으니 말이다. 뭐.. 내가 모르는 무언가가 있는건가?

78 페이지

  • basename()에 대한 설명으로 파일 패스에서 파일의 확장자를 제외한 이름을 반환합니다.라고 되어 있는데 잘못된 설명이다. 기본적으로 basename은 파일의 반환하는 함수이고, 두번째 인자에 따라서 확장자를 제거해 주던지 아니면, 그대로 두던지 한다. 심지어 80페이지의 실제 출력 결과물에서도 확장자가 제거 되지 않고 nodepad.exe가 출력 된다.

84 페이지

  • 그리고 문자열은 큰 따옴표(" ") 또는 작은 따옴표(' ')를 사용하여 표기합니다. 라고 되어 있다. 이쪽 세상에서는 큰 따옴표보다는 작은 따옴표를 훨씬 더 많이 쓴다. 이 책에서 나오는 예제들도 대부분(?) 작은 따옴표를 사용하고 있다.

94 페이지 ~ 96 페이지

  • 94 페이지부터 96페이지까지 있는, push, pop, shift, unshift 관련 예제들은 의도를 제대로 표현하지 못한다. 이 함수들은 배열에 어느곳을 기준으로 아이템을 추가/삭제하는지가 중요한데, 예제에서는 단순히 배열의 count 만 하고 있다. 정확하게 동작하는지 확인해 보려면, 최소한 push, pop, unshift 를 사용하기 직전과, 사용한 직후에 console.dir(Users); 라도 있어야 확인할 수 있다.
  • 96 페이지 이후에 나오는 delete, splice, slice 의 경우에는 console.dir(Users); 로 화면에 객체 정보를 출력해 해당 함수들이 잘 동작하는지 확인하도록 예제가 만들어져 있다.

105 페이지

  • 사소하긴 하지만, 예제의 제일 아래쪽줄 바로 윗줄에 '객체의 walk(10)을 호출합니다.' 라고 되어 있는 부분에서 객체의 앞에 공백이 하나 들어가야 한다. 107 페이지의 결과에서는 Person.name 과 '객체의' 라는 글자 사이에 공백이 있다.

107 페이지

  • prototype에 대한 설명이 너무 퉁 쳐서 되어 있다. 메모리를 효율적으로 관리한다라고 하기에는 내부 동작이 복잡하기 때문에 이해하고 넘어 가는 것이 좋다. 오승환님의 글 : [Javascrip] 프로토타입 이해하기 라는 글을 보면 이해하기 쉽게 잘 설명 되어 있다. 물론 초보자라면 읽어도 이해하기 어려울 수 있으니, 그 때는 그냥 패스.

109 페이지

  • 이 작업을 쉽게 할 수 있도록 노드에서 미리 만들어둔 모듈이 url 모듈입니다. 라는 말이 있다. 실제로 url 모듈이 이러한 역할을 하지만, url 모듈에서는 "한글 도메인"을 "영문 도메인"으로 바꾸는 다른 기능들도 가지고 있다. 그러므로, 정확하게 바꾸자면 노드에서 미리 만들어 둔 url 모듈을 사용하면 이 작업을 쉽게 할 수 있다. 고 되는게 정확하겠다. 맞다. 그냥 꼬투리 잡는거다. ㅋㅋ.

119 페이지, 120 페이지

  • readFile(filename, [encoding], [callback]) 이라고 되어 있는데, 정확한 스펙은 readFile(filename, [options], callback) 이다. options에는 encoding을 적을 수 있기 때문에 그 부분은 적당히 맞다고해도, callback은 반드시 필요한데, [callback]으로 표시해서 마치 생략할 수 있는 것 처럼 표기 했다. 그러므로 수정되어야 한다. writeFile, open, read, write, close 모두 callback을 생략해서는 안된다.

127 페이지

  • 주의 상자에 기존 output2.txt 파일을 삭제한 후 output.txt 파일을 output2.txt 파일로 복사하는 과정이 비동기 방식으로 처리되므로 화면에 출력되는 순서는 다를 수 있습니다. 라고 되어 있는데.. 단순히 출력만 다른게 문제가 아니다.
  • 파일을 삭제하는 fs.unlink 역시 비동기로 동작된다. 즉, 언제 파일이 지워질지 모르는 상태에서 다음 코드인 infile.pipe(outfile)을 수행하게 된다. 이 때 fs.unlink보다 infile.pipe(outfile)이 먼저 실행 완료되면, 파일을 "복사"를 한 뒤, 파일을 "삭제"하게 되므로 복사가 제대로 되지 않을 수 있다.
  • 그러므로 단순이 출력만 다른 문제가 아니라, 코드 자체가 오류를 일으킬 수 있도록 되어 있다는것이 문제다.
  • 제대로 수정할 것이라면, fs.unlink의 callback 함수 안에서 복사하는 동작을 넣어야 한다고 생각된다.
  • 아님 말고. ㅋ

137 페이지

  • server.listen(port, host, '50000', function() { ... 부분에서 좀 잘못 된 부분이 있다. 물론, '50000'의 위치에 들어가야 하는 정보는 backlog 라는 값이 되어야 하는데, API 정의상에서는 이 값이 <number>여야 한다.
  • 물론 코드를 동작시켰을때, 잘 동작할 수도 있다. javascript의 오묘한 형 변환이 있기 때문이다. ㅎ. 물론 난 실제로 코드를 동작시켜서 확인해 보지는 않았다. ㅎㅎ.

145 페이지

  • 이 파일을 실행한 후 웹 브라우저에서 요청을 보내면 같은 결과를 볼 수 있습니다. 라고 되어 있다. 같은 결과를 볼 수 있는것이지 실제로 같은 응답을 보낸것은 아니다.
  • pipe를 이용해서 데이터를 바로 쏴 버리면, 현재 보내는 파일의 content-type을 보내지 않게 되므로, 웹 브라우져가 알아서 보여주는것이다.
  • 헤더 정보가 없는 응답

  • 그렇기 때문에 책에서도 이 방법으로 코딩을 했을때 헤더를 설정할 수 없는 등의 제약이 생기므로 필요할 때만 사용하길 권합니다. 라고 적어 둔 것이다.

  • 헤더도 제대로 셋팅하고 파일도 전달 하고 싶다면, infile.pipe(res); 바로 윗 줄에 res.writeHead(200, {'Content-Type': 'image/png'});를 추가해 주면 Content Type 헤더도 제대로 전달 할 수 있다.

  • 헤더 정보가 잘 추가 되어 있는 응답

149 페이지

  • 정박사의 한마디 부분 중 GET 방식은 헤더 부분에 요청 정보들을 넣어 보내고라는 부분이 있다. 정확하게 말하면 GET 방식은 URL 부분에 요청 정보를 전달하는것이다.
  • GET 이던 POST던 상관없이(심지어 PUT이나 DELETE에도) 헤더 부분에 요청 정보를 넣어 보낼 수 있다.
  • 초보를 위한 책이기 때문에, 이 모든것을 구체적으로 설명할 수 없다는것을 독자는 이해해야 한다.
  • 클라이언트에서 어떤 Method를 쓰던 request 헤더에 부가적인 정보를 보내고, 서버에서 그 정보를 받아서 처리하겠다고 약속하면 된다.

164 페이지

  • 첫 번째 코드 예제 중에서 app.use('/public', static(path.join(__dirname, 'public'))); 부분이 잘못 되었다.
  • 코드의 직전 설명에서는 [public] 폴더에 있는 모든 파일을 웹 서버의 루트 패스로 접근할 수 있도록 만들고 싶다면 이라고 표현되어 있다. 이 말대로 동작하려면 코드는 app.use(static(path.join(__dirname, 'public'))); 이 되어야 할 것이다.
  • 다음 페이지의 3번째 예제는 설명이 제대로 되어 있다.
  • 167 페이지의 예제에서도 app.use('/public', static( ... ) )으로 되어 있는데, 이 역시 app.use( static( ... ) )로 되어야 한다.
  • 그리고 static 이라는 이름의 변수를 쓰는건 좋지 않다. 오해를 일으킬 수도 있고, 추후 TypeScript 등을쓰게 되면 또 문제가 된다. 그러므로 static이라는 이름의 변수는 피하도록 하자.
  • 참고로 Express 4.x 이후로는 express.static 미들웨어를 기본으로 제공한다고 한다. 그래서 코드를 쓸 때 그냥, app.use(express.static('public')); 형태로 쓰면 된다. 여러 디렉토리를 설정할 수도 있다고 한다.
  • express.static

168 페이지

  • 아래쪽을 보면 서버 코드에서 use() 메소드로 설정한 함수는 login.html 문서에 접근했을때는 호출되지 않습니다. 라고 되어 있다. 근데... 잘은 모르지만... 아마도... 이 설명은 잘못 되었다.
  • 서버 코드에서 app.use( '/public', static(...)) 부분이 실행되었기 때문에, public 디렉토리에서 login.html을 찾아서, 웹 브라우져로 내려 주었기 때문에, 웹브라우저에서 해당 HTML을 볼 수 있게 된 것이다.
  • 그러므로 정확하게 말하면 서버코드에서 app.use( static(...) ) 메소드로 설정한 함수가 동작했고, 그 다음 app.use() 함수는 호출 되지 않습니다. 라고 이해하는게 좋겠다.
  • 그렇다면 왜, app.use(static(...)) 다음에 우리가 정의한 미들웨어는 실행되지 않는가? 바로, static(...) 함수 안에서 error가 나지 않는 이상 next() 함수를 호출하지 않도록 코드가 만들어져 있다. 관심이 있다면 직접 소스 코드를 확인해 보자.

262 페이지

  • 세번째 줄 I accept th license terms -> I accept the license termse가 빠진 듯 하다.

276 페이지 277 페이지

  • 276 페이지 select ?? from ?? where id = ? and password = ? 부분과 227페이지 SQL문 안에 들어 있는 ?? 또는 ? 기호를 대체한 후 다음과 같은 SQL 문을 만들어 냅니다. 에서 어떤때는 ?? 를 쓰고, 어떤때는 ?를 쓰는데 이건 오타가 아니다.
  • ?? 는 '' 없이 그냥 값이 대체 될 때 사용되고, ?는 ''를 감싸서 대체 된다.
  • 277 페이지 중간에 있는 select id, name, age from users where id = 'test01' and password = '123456' 을 보면 잘 알 수 있다.

348 페이지

  • 마지막 예제에서 <h2><% = title %></h2>가 있는데 %=를 붙여 적어야 한다. 즉, <h2><%= title %></h2> 가 되어야 함.
  • 그 외, 다른 곳에서도 <% =와 같이 띄워쓰는 코드들이 보이는데 이것은 모두 오타이다. 그러므로 다 붙어 있다고 생각하면 된다.
  • 그리고 여기에서 <%를 쓰는 경우와 <%=를 쓰는 경우가 있는데, 이것에 대한 자세한 사용법은 ejs홈페이지 에서 Tags 부분을 확인해 보면 좋다.

8장 뷰템플릿 적용하기...

  • 뷰 템플릿은 ejs와 pug에 대한 설명이 나온다.
  • 기존에 HTML을 알고 있는 사람이라면 ejs가 훨씬 더 직관적이다. 반면 pug는 pug만의 문법을 따라야 한다는 불편함이 있다.
  • 물론 pug가 HTML tag를 모두 적지 않아도 된다는 장점이 있지만, 요즘에는 대부분 IDE 툴에서 HTML 자동 완성을 제공해 주므로, 크게 차이가 나지 않을 것으로 보인다.
  • 암튼 난 ejs 가 훨씬 더 편해 보인다. 예전에 php를 해서 그런지 ejs가 훨씬 더 익숙해 보인다.

373 페이지

  • 두번째 예제 박스에서 passport.use(new LocalStrategy( 부분은 passport.use('local', new LocalStratgy(로 바꾸는것이 책을 읽는데 좀 더 수월하다. 다음장인 374 페이지의 윗 부분 그림에도 스트래티지 설정이라는 부분에 보면 'local'을 설정해 둔 것을 볼 수 있다.
  • 다만 'local'을 생략했다고 해서 잘못 동작하는것은 아닌데, passport.use()함수를 호출할 때, Strategy의 이름을 설정해 주지 않는다면, Strategy에서 name 값을 얻어와 셋팅하도록 되어 있기 때문이다.
  • https://github.com/jaredhanson/passport/blob/master/lib/authenticator.js
  • LocalStrategy의 코드를 보면 자신의 name 값을 설정하는 코드를 찾을 수 있다.
  • https://github.com/jaredhanson/passport-local/blob/master/lib/strategy.js
  • 그러므로 passport.use(new LocalStrategy(로 설정했다고 해도, 가져다 쓸 때는 passport.authenticate('local', ...) 으로 호출 할 수 있게 된다.

427 페이지

  • attach(httpServer, options)는 정확하게 하면, attach(httpServer[, options])이다. 즉, Options는 생략 가능. 물론 책에서 일일이 설명하기 어려우니 생략했을 것이라고 생각한다. 글쓴이보고 뭐라고 하지 말길...
  • 그 아래에 있는 listen(httpServer, options) 역시 마찬가지다.

431 페이지

  • 예제 중에서 socket.on(... 부분의 코드에서 들여쓰기가 잘못 되어 있으니 주의해서 볼 것.

435 페이지

  • 예제나 책 설명 중에 recepientrecipient의 오타이다. 하지만 책 전반에 걸쳐 오타인 recepient를 사용했으니, 실제 코드에서는 별 문제가 없을 것으로 예상된다.
  • 나도 자주 틀리는 단어라.. ㅎㅎ. 이해가 된다. ㅋㅋㅋㅋㅋ.

481 페이지

  • 이 callback 함수는 두 개의 파라미터를 전달받을 수 있는데, 첫 번째 파라미터는 오류 전달을 위해 사용하고 두번째 파라미터는 정상적인 데이터를 전달 할 때 사용합니다. 라고 설명되어 있다.
  • 487 페이지에 실제로 에러가 난 상황을 가정하고, 첫번째 파라미터에 "정보"를 넘기고 있는것을 볼 수 있다. 481 페이지의 내용을 대충 읽으면, 487 페이지의 내용을 이해하기 어려울 수 있을것 같아, 기록해 둔다.

484 페이지

  • 제일 아래 표에서 result : 응답 데이터가 배열 객체로 들어 있습니다. 라고 되어 있다.
  • 여기서는 성공한 경우에 대한 정보만 표로 나타내고 있다. 실패한 경우에는 error이라는 속성에 정보가 채워져 있다. 이 내용은 489 페이지에 설명되어 있다.
  • 다만 실패한 경우에 대한 설명은 표로 설명되어 있지 않아 놓치기 쉬울 것 같이 기록해 둔다.

621 페이지

  • 예제의 하단을 보면 Entities : Entities 부분이 있다.
  • 또한, 622 페이지 ejs 예제를 보면 var entities = new Entities(); 코드가 있다.
  • 뜬금 없이 갑자기 Entities를 사용하고 있는데, 이건 책에 코드가 누락되어 있기 때문이다.
  • 619 페이지 코드에서 제일 윗 줄에 .... 위치에 다음의 코드가 들어가야 한다. var Entities = require('html-entities').AllHtmlEntities;.
  • 인터넷에세 예제를 다운로드 받아보면 추가 되어 있으나, 책에서는 생략되어 있어 의아하게 생각할 수 있는 부분이다.
  • 책에서는 Entitites에 대한 설명을 아예 없다.
  • html-entities 모듈은 HTML을 인코딩/디코딩 시켜주는 역할을 한다. 설치는 npm install html-entities --save로 설치 할 수 있다.


[도서]타입스크립트 마스터 2/e

나단 로젠탈 저/김유성 역
에이콘출판사 | 2018년 03월

내용     편집/구성     구매하기

서두

자바스크립트를 공부하고, 실제로 사용하려고 했지만, 너무나 어려웠다. 가장 어렵다고 생각한 부분이 "자동완성"을 제대로 지원하지 않는것.

Type이 정확하지 않기 때문에, 내가 parameter로 전달해야 하는것도 명확하지 않았고, 모든것을 다 알고(혹은 외우고) 호출해야 하는 일이 어려웠다.

그래서 타입스크립트를 공부해 보기로 결심.

에이콘 출판사의 "타입스크립트 마스터 2/e - 예제로 배우는 타입스크립트"를 구매 했다.

출판사에 있는 정오표에 표시된 것 말고도 잘못 된 곳이 보여, 이곳에 정리해 두고자 한다. 지금 발견한건 딸랑 하나라.. 나중에 더 추가 될 수 있을지 모르겠다.

책을 다 읽었다. 당근 완벽하게 모든 내용을 이해한건 아니다. ㅋㅋ 아래 내용중 내가 잘 모르는 상태로 "잘못됐다"라고 이야기 하는것도 있으니, 이 글을 읽는 사람이 잘 가려서 읽기를 바란다.

책 후기

  • TypeScript의 문법은 거의 java와 비슷하다. 좀 다른게 있다면.

    • 변수나 함수의 type을 정의 할 때, 변수명 뒤 쓰는 형태 public id : string;
    • interface 정의에 field도 정의할 수 있음 interface A { id:string }
    • field에 접근할 때, get set 키워드를 통해서 hooking 할 수 있음 get id() { return this._id; }
    • 읽기 전용 속성은 final 대신, readonly readonly name: string;
    • 여러개의 type을 받고 싶을때는 Object 대신 any var a : any = "aa"
    • 여러개의 정해진 type(Union)을 받고 싶을때는 Object 대신 | var a : string|number;
    • 함수의 파라미터에서 같은 타입의, 다른 갯수에 대한 오버로딩시 모두 각각 정의하는 대신 ? 사용 funnction a( b: string, c?: string, d?: string) { ... }
    • 함수의 파라미터에서 타입이 다른 오버로딩시 모두 각각 정의하는 대신 아래 문법 사용

        function a ( b: string, c: string) : string;
        function a ( b: number, c: number) : number;
        function a ( b: any, c: any) : any {
            // code
        }
      
    • 상속 받은 클래스의 생성자에서는 반드시 super()를 수동으로 불러줘야 한다. Java에서는 super()가 자동으로 호출 되지만, 타입스크립트는 그렇지 않음. 자동으로 호출해 주자는 건의(?)가 많았지만, JavaScript의 super-set이라는 등의 이유로 안된듯 하다.

정오표 및 이해하기 어려운 곳 설명

3장 인터페이스, 클래스, 상속

216 페이지

  • Simple Class는 id, name의 속성과 -> Simple Class는 id 속성과
    • Simple Class에는 name 속성이 없다.

156 페이지

  • myClosure; -> myClosure();
    • 예제 소스에서 의도한것은 myClosure라는 함수가 실행되는것을 의도한 것이다(p157페이지의 상단 설명). 그러므로 함수 실행을 위해서 마지막에 () 를 붙여 주어야 한다.

159 페이지

  • 제일 아래의 예제 처음에 아래의 코드 추가

    enum PersonCategory {
        Audlt,
        Infant,
        Child
    }
    
    interface IPerson {
        Category: PersonCategory;
        canSignContracts(): boolean;
        printDetails(): void;
    }
    
  • 아마도 PersonCategory에 관한 enum과, IPerson이라는 interface 관련 코드가 아예 빠진것 같다. p160 내용이나, 그 뒤의 예제 결과등을 참고하면, 위의 코드가 있어야 될 듯 하다.

174 페이지

  • 제일 아래의 예제 코드에서 static staticName: string; -> static name: string;
    • 다음페이지에 나오는 출력 결과물과, 설명을 보면 코드상의 속성 이름이 staticName이 아니라 name이 되어야 한다.

203 페이지 (오타아님)

  • 유창한 구문으로 함수에 프라미스를 -> 플루언트 구문으로 함수에 프라미스를
    • Fluent의 번역을 "유창한"이라고 했다. 그래서 오히려 이해하기 어렵다. fluent 에 대한 개념은 여러 라이브러리의 사용에서 나오므로, 그냥 "플루언트"라고 그대로 적는게 어떨까 싶다. "데코레이트"도 그대로 사용했으니깐. 324페이지에도 "유창한"이라고 적혀 있으니, 이후에 나오는건 모두 걍 fluent라고 생각하면 된다.

226 페이지

  • containsErros 메서드와 ErrorHelper.trace 메서드를 -> ErrorHelper.containsErrors 메서드와 ErrorHelper.trace 메서드를
    • ErrorHelper는 containsError와 trace 메소드를 모두 가지고 있는데, 한쪽에만 ErrorHelper의 메소드인것 처럼 적어 두었다.

261 페이지

  • 정의에 모델 속성을 할당하려면 model: NoteModel 구문이나 -> 정의에 모델 속성을 할당하려면 model = NoteModel 구문이나
    • 260페이지의 마지막에서 이미 model: NoteModel은 오류가 발생한다고 적혀 있다. 그러므로 261페이지의 내용은 model = NoteModel 이 되어야 한다.

274, 463 페이지 (오타아님)

  • MVC는 모델-뷰-컨트롤러의 두 문자 집합으로 -> MVC는 모델-뷰-컨트롤러의 앞 글자의 집합으로
  • 객체지향 모범 사례의 두 문자를 모은 SOLID 디자인 -> 객체지향 모범 사례의 앞 글자를 모은 SOLID 디자인
    • 두 문자는 머리 두(頭)를 이야기 한 것으로 보인다. 그러므로 읽기 쉽게 "앞 글자" 라고 적어두는게 더 읽기 좋겠다.

323 페이지

  • Jasmine uses a simple format for writing tests. Consider the following TypeScript code: -> 삭제
    • 이미 위에 한글로 해석이 되어 있는데, 코드 쪽으로 설명이 내려와 있다. 그러므로 삭제

334 페이지, 335 페이지

  • doCallback 함수 -> doCallBack 함수
    • 예제에서는 "B"지만, 설명에서는 어떤 때는 "B", 어떤 때는 "b"로 사용한다. 그러니 잘 읽어내도록 하자. 심지어, 334페이지 아래쪽에는 let doCallback 으로 변수를 하나 만들어서 쓰고 있어서 더 혼동이 될 수 있다. 예제를 만들때 요런 점도 좀 고려해서 만들었으면 좋았을 텐데...

341 페이지, 342 페이지

  • jasminjquery -> jasmin-jquery
    • 라이브러리 이름이니 정확하게 "-"를 포함해서 적어야 한다.

363 페이지

  • Id: 0, DisplayName: "none"}}); -> { Id: 0, DisplayName: "none"}});
    • SelectedItem의 값으로 Id와 DisplayName을 넣는 Struture를 넣어야 하는것으로 보인다. 그렇게 되려면 "{"를 제일 앞에 추가해 줘서 객체(?) 형태로 만들어야 한다.

09장 타입스크립트 호환 프레임워크 테스트 는 생략함

  • TypeScript 자체를 공부하기 위해서 책을 보는것이라. 지금 당장은 테스트용 프레임워크를 열심히 볼 필요는 없다고 판단. ㅋ. 그래서 걍 이 부분은 읽지도 않고 패스함.ㅋ.

417 페이지

  • mod1.print(); -> m1mod1.print();
    • 첫번째 예제에서 let m1mod1 으로 정의해서 쓰고 있기 때문에, 다음줄에 있는 코드는 당연히 m1mod1.print(); 가 되어야 한다.

426 페이지 (오타아님)

  • 글 내용을 보면, "main.js파일에서는..." 이런 내용이 나오는데, 어디에도 그 main.js 파일을 찾을 수 없다. 그냥 작가가 있다고 생각하고 이야기 한 것인지 모르겠다. 그래서 책 내용을 읽을때, 독자도 상상력을 가지고 읽으면 될 것 같다.

429 페이지

  • 항목 이름은 'jasmineboot'로 -> 항목 이름은 'jasmine-boot'로
    • 소스코드에서는 물론이고, 직전의 설명에서도 'jasmine-boot'로 설명 되고 있다.

432 페이지

  • 다음 AMD 오류인 filenot-found 오류일 수 있다. -> 다음 AMD 오류인 file-not-found 오류일 수 있다.
    • 이전 설명에서도 file-not-found 와 같이 중간에 모두 - 을 넣어 두었다.

436 페이지 (오타아님)

  • 중간에 보면 http-server를 실행하고 결과를 보여주는 설명이 있는데, http-server를 설치하는 방법은 설명도 안 해 줬다. ( 설마.. 9장에서 해 줬나? ). http-server를 설치하려면 console(cmd)창에서 아래의 명령을 입력해 주면 된다.
  • npm install http-server -g
  • 그 이후 http-server를 실행시키면 된다.

448 페이지, 451 페이지, 565 페이지 등 (오타이님)

  • {{{body}}}

    • handlebars 템플릿은 일반적으로 {{ }} 처럼, 이중 괄호를 2개만 쓴다. 그런데 예제에서는 {{{ }}} 에 대한 설명 없이 body만 {{{body}}}로 사용중이다.
    • handlerbars는 {{ }} 를 사용하게 되면, 단순 String으로 치환하는것 이외에, HTML Tag와 관련되는것들을 모두 화면에 출력할 수 있도록 치환해 준다. 예를 들어 title이 "제목은 귀여워 >_<" 와 같다면, "제목은 귀여워 &gt;_&lt;" 와 같이 치환한다.
    • 하지만 {{{ }}} 를 사용하면 치환하지 않고, 그대로 String이 들어가게 된다. 여기에서는 {{{body}}} 영역에 각종 HTML 코드(<p> 나 <br>등)가 들어가야 페이지 HTML 페이지 구성을 할 수 있기 때문에 {{{ }}}를 사용한 것이다.


Facebook에서 Android dex를 압축(?) 해 주는 툴을 만들어 두었는데, 이것의 이름이 ReDex다.


https://github.com/facebook/redex


Docker로 Ubuntu 14.04 container를  만들고, 위 링크에 있는 가이드 문서대로 따라 했지만 문제가 발생했다.

몇 가지 빠진 부분이 있어 내가 했었던 작업의 기록을 남겨 둔다.

( 이 과정을 Dockerfile로 만들면 좋겠지만, 귀찮아서 통과 )



1. Ubuntu 14.04 로 Docker Container 만들기 

docker run -i -t --name ubuntu14.04_redex ubuntu:14.04 /bin/bash



2. 디렉토리 이동 ( root의 home directory에 모든것을 설치할 예정 )

cd ~



3. redex 가이드 문서에 Ubuntu 14.04 부분을 실행하기 전에 아래의 것을 먼저 실행해야 한다.

redex 설치 및 사용할 때, 그리고 인터넷에서 android sdk 를 다운로드 받을 때 필요하다.

apt-get update

apt-get install curl

apt-get install unzip

apt-get install openjdk-7-jdk

apt-get install wget



4. android sdk를 먼저 설치해야 한다. ( 아래 과정 중 test 과정에서 java를 컴파일 하고, 이를 dx로 묶는 과정이 있다. )

wget https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz 

tar zxvf android-sdk_r24.4.1-linux.tgz 

cd android-sdk-linux

tools/android update sdk --no-ui

( 이후 라이센스에 동의하라고 하면 y를 눌러 주면 된다. 혹시 화면이 멈추면 엔터를 한번 쳐 주면 라이센스 동의 문구가 나온다. )

tools/android update sdk -u -a -t 4,5

( 상황에 따라서 뒤에 있는 숫자인 4,5 를 바꿔야 하는 경우도 있다. 숫자에 맞는 version을 다운받게 된다. 목록을 알고 싶다면 tools/android list sdk -a -u 를 쳐서 번호를 확인하도록 하자. 여기서는 23.0.3을 사용한다. 24는 java version 8이 필요하기 때문에 openjdk 7으로 실행할 수 없다. )



5. ~/.bashrc 파일의 제일 아래쪽에 아래 내용을 추가하도록 하자. ( vi ~/.bashrc ) 

ANDROID_SDK=/root/android-sdk-linux/

PATH=$PATH:/root/android-sdk-linux/build-tools/23.0.3/:



6. 이후 bashrc 파일에 넣어 둔 환경을 현재 터미널에도 적용하기 위해 source 명령으로 상태를 업데이트 해 준다.

source ~/.bashrc



7. redex 가이드 문서에 따라서 각종 tool 다운로드 및 설치 ( 이하의 과정은 달라졌을 수도 있으니, 공식 홈페이지에 가이드 문서를 반드시 다시 확인하자. )

sudo apt-get install \
    g++ \
    automake \
    autoconf \
    autoconf-archive \
    libtool \
    libboost-all-dev \
    libevent-dev \
    libdouble-conversion-dev \
    libgoogle-glog-dev \
    libgflags-dev \
    liblz4-dev \
    liblzma-dev \
    libsnappy-dev \
    make \
    zlib1g-dev \
    binutils-dev \
    libjemalloc-dev \
    libssl-dev \
    libiberty-dev \
    libjsoncpp-dev



8. redex 가이드 문서에 따라서 다운로드, 빌드, 설치

git clone https://github.com/facebook/redex.git

cd redex

autoreconf -ivf && ./configure && make

sudo make install



9. 설치가 다 되었으면 잘 동작하는지 체크 한다.

./test/setup.sh

cd test

make check

근데 여기서 에러가 난다.. 이유는 모르겠음.. ;; 요건 무시해도 된다.



10. 이후 redex 명령을 이용해서 apk를 redex 시킬 수 있다.

( 만약 zipalign 문제가 생기면, 위에 설명한 환경 설정이 제대로 안 된 것이다. ./bashrc 파일에 ANDROID_SDK를 확인해 보도록 하자. )

redex a.apk -o a.redex.apk




그 결과 다음과 같은 결과를 얻었다.

c.apk -> c.redex.apk : 44.8M -> 44.5M

s.apk -> s.redex.apk : 39.8M -> 39.4M

w.apk -> w.redex.apk : 38.4M -> 38.1M

t.apk -> t.redex.apk : 33.8M -> 33.4M

원본 apk는 이미 proguard를 거친 뒤였음에도 약 250kb ~ 400kb 정도 용량이 줄어 들었다.

( 실제로 동작하는지는 확인하지 않았다 ;; ㅎㅎ )


  1. 발자국 2016.10.21 00:07 신고

    빠른나이는 아니지만 뒤늦게 프로그래밍에 재미를 찾아 공부하고있는 백수입니다.
    검색중에 들렸습니다.
    2003년부터 올해까지 꾸준히 공부하시고 포스팅 하신 흔적보고 감동받아 이렇게 덧글 작성해봅니다.
    존경합니다!!

    • 2016.12.20 12:01 신고

      오랫동안 관리되지 않던 블로그라 부끄럽습니다. 즐거운 나날들 보내세요~

자바스크립트를 공부하기로 했다.

그래서 책을 구매하려고 보니.. 제일 유명한게 "자바스크립트 완벽 가이드".

그런데.. 5e은.. 잘못 번역되어 있는게 너무 많아.. 욕을 꽤나 먹는 상황.


마침 3월 말에, 6e이 나와서.. 이 책을 구매 했다.


하지만, 여전히 몇가지 잘못 된 부분이 보여. 이곳에 정리하고자 한다.

인사이트에 올려두면 더 좋겠지만. 오랜만에 내 블로그에 글도 좀 적고..

꾸준히 공부하는 내용도 정리 좀 하고... 할 겸.


내용은 발견하는대로 귀찮지 않으면 업데이트 할 예정이다.



8페이지 중간 부분 수정


var square = function(x); { // 여기서 함수는 값이 되고, 변수 square에 할당된다.

var square = function(x) { // 여기서 함수는 값이 되고, 변수 square에 할당된다.


; 를 제거해야 한다.


9페이지 윗부분 수정


function abs(x) {    // 절대 값을 계산하는 함수를 정의한다.

    if ( x>= 0 ) {   // 괄호 안의 표현식 값이 참이면

        return x;    // if 절 안의 코드를 실행한다.

}                    // if 절의 끝을 나타낸다.

function abs(x) {    // 절대 값을 계산하는 함수를 정의한다.

    if ( x>= 0 ) {   // 괄호 안의 표현식 값이 참이면

        return x;    // if 절 안의 코드를 실행한다.

   }                 // if 절의 끝을 나타낸다


로 괄호의 위치가 잘못 되었다.


53페이지에서 String Warpper 객체 및 동작에 대한 설명 추가


var s = "test"; // 이 문자열을 사용한다.

s.len = 4;      // 문자열 프로퍼티에 값을 할당한다.

var t = s.len;  // 프로퍼티를 참조하라.


이 코드를 실행해 보면 t 값은 undefined이다. 2행은 생성된 임시 String 객체의 len프로퍼티에 4를 할당한다. 그리고 임시 객체는 바로 삭제 된다. 3행은 기존 문자열 값과 같은 값을 가진 새로운 String 객체를 생성하고 len 프로퍼티를 읽으려고 한다. 이 프로퍼티는 존재하지 않아서 undefined로 평가된다. ... 문자열이나 숫자, 불리언 값에서 프로퍼티(혹은 메서드)의 값을 읽으려고 할 때, 문자열, 숫자, 불리언 값이 객체처럼 동작하는 것을 보여준다. ... 값을 할당하는 것은 임시 객체에서 수행되며, 지속되지 않는다.


위의 문장을 이해하기 어려웠는데, 52 페이지에서 마지막에 설명된 내용과 53페이지의 마지막 내용을 잘 읽어보면 이해할 수 있다.


// javascript 에서 s 는 test라는 값을 가지는 단순한 문자열 리터럴일뿐이다.

var s = "test";


// javascript 에서 s의 프로퍼티에 접근하는 순간, s를 String 객체로 만든 뒤에 처리한다. 그 후 사용하고 난 String객체는 버린다.

s.indexOf(" ");   


// 위의 문장은 아마도 내부에서는 

// var anonymousStringObject = new String(s); 

// anonymousStringObject.indexOf(" ");

// 

// anonymousStringObject = undefined; 

// 또는 anonymousStringObject = (function () { return; })(); 로

// 처리가 될 듯 함.


// java 에서 "test" 자체가 String object이다. variable의 type역시 String class으로 받게 된다.

// java

String str = "test";


// 하지만 javascript에서는 "string"이라는 type이 따로 있고, new String(..)으로 정의할 수 있는 String object가 따로 있다.

// javascript

//

// typeof("AA") : "string"

//

// var str = new String("AA");

// typeof(str) : "object"





 63 페이지 중간 부분(3번째 단락)


+와 == 연산자는 객체를 원시 타입으로 변환할 때 Data 타입 객체는 특별하게 취급한다.

 +와 == 연산자는 객체를 원시 타입으로 변환할 때 Date 타입 객체는 특별하게 취급한다.


로 Data를 Date로 변경해야 한다.



 63 페이지 중간 부분 Date 동작이 특이한 점


javascript에서 객체타입이 원시타입으로 변환 될 때는, 기본적으로 객체에서 숫자로의 변환이다. 이 떄는 valueOf()가 사용된다. Date 객체가 참 특이하게, +와 == 연산자랑 같이 사용 할 때는 toString()이 사용되어 string type으로 변환되고, 나머지인 < 나 -(빼기) 등의 연산자랑 같이 사용 할 때는 valueOf()이 사용된다.



 66 페이지 두번째 소스 들여쓰기 잘못.


var scope = "global scope";


function checkscope() {

    var scope = "local scope";

        function nested() {

            var scope = "nested scope";

            return scope;

        }

    return nested();

}

checkscope();


var scope = "global scope";


function checkscope() {

    var scope = "local scope";

    function nested() {

        var scope = "nested scope";

        return scope;

    }

    return nested();

}

checkscope();


와 같이 들여쓰기가 잘못되었음.



 66 페이지 마지막 예제... 자바스크립트알못이지만... 설명이 애매하다... 또한, 들여쓰기도 잘못되어 있다.


function test(o) {

    var i = 0;

    if ( typeof o == "object") {

        var j = 0;

        for ( var k=0; k < 10 ; k++ ) {

            console.log(k);

        }

        console.log(k);

    }

    console.log(j);   // j는 정의되어 있고, 초기화 되어 있지 않을 것이다.

}



해당 부분은 javascript의 특징인 hoisting 을 설명하는 부분이다. hoisting이란, 변수의 정의 및 할당이 실제 코드의 순서에서 아랫쪽에 되어 있다고 하더라고, 해당 변수의 정의를 상단으로 끌어 올린것으로 처리 된다는 설명이다. 또한, javascript에서는 변수의 scope가 블록 기호인 { } 로 묶이는 부분에 대해서 scope를 가지는것이 아니라, 함수 전체에 영향을 받는것으로 되어 있다.


예제에는 j라는 변수가 if 문 안에서 정의되어 있으나, console.log(j)에서도 j의 선언부가 hoisting 되어서 접근이 가능하다는것을 표현하고 싶었던것 같은데, 그렇다면 parameter로 받는 o의 상태에 따라 j가 0이 될 수도 있고, undefined 상태일 수도 있다고 설명을 좀 더 정확하게 적었어야 했다.


hoisting 상태를 고려한다면 위의 코드는 아래와 같이 변할 것으로 예상된다.



function test(o) {

    var i = 0;

    var j;

    if ( typeof o == "object") {

        j = 0;

        for ( var k=0; k < 10 ; k++ ) {

            console.log(k);

        }

        console.log(k);

    }

    console.log(j);   // o가 object가 아닌 경우, j는 정의되어 있고, 초기화 되어 있지 않을 것이다.

}




73 페이지 첫번째 소스 코드


[?]          // 빈 배열: 대괄호 안에 표현식이 없으면 원소가 없음을 말한다.

[]        // 빈 배열 : 대괄호 안에 표현식이 없으면 원소가 없음을 말한다.


? 가 필요 없이 들어가 있다.



73 페이지 마지막 소스 코드


var p = { x:2.3, y:-1.2 };    // 두개의 프로퍼티를 가진 객체

var q = {?};                  // 프로퍼티가 없는 빈 객체

q.x = 2.3; q.y = -1.2;        // 객체 q와 p는 같은 프로퍼티를 갖는다.


var p = { x:2.3, y:-1.2 };    // 두개의 프로퍼티를 가진 객체

var q = };                  // 프로퍼티가 없는 빈 객체

q.x = 2.3; q.y = -1.2;        // 객체 q와 p는 같은 프로퍼티를 갖는다.


?가 필요 없이 들어가 있다.



83페이지 마지막 예제


1 + 2                   // => '3'

"hello" + " " + "there" // => 'hello there'

"1" + "2"               // => '12'

1 + 2                   // => 3

"hello" + " " + "there" // => 'hello there'

"1" + "2"               // => '12'


문자 3이 아니라, 숫자 3으로 계산되어야 한다.



84페이지 중간 예제


 1 + {?}     // => "1[object Object]" : 객체를 문자열로 바꾼 후 이어붙이기

 1 + {}     // => "1[object Object]" : 객체를 문자열로 바꾼 후 이어붙이기


로 필요 없이 ? 가 들어가 있다.



 94 페이지 첫번째 예제가 나온 뒤 4번째 줄에 대한 설명


또한 우변 피연산자가 함수가 아니라면 TypeError 예외가 발생한다.

일반적으로는 "함수"가 아니라, "클래스"가 아니라면 TypeError이 발생한다고 생각 할 수 있다.

하지만 javascript에서는 class라는 형태를 function으로 정의 하기 때문에, 함수가 아니라면 TypeError가 난다고 말 하는게 맞는듯 하다.



97 페이지 첫번째 예제 설명이 명확하지 않음


// max_width가 정의되어 있으면 이것을 사용한다.

// 이 외의 경우 preference 객체에 속한 값을 찾아 본다.

// 그것조차 정의되어 있지 않을 경우 하드코딩된 상수를 사용한다.

var max = max_width || preferences.max_width || 500;

 

위 설명에서 잘못된 부분이 있다.

"max_width가 정의되어 있으면 이것을 사용한다." 부분이다. 정의되어 있는것은 당연히 중요하고, max_width가 어떤 값을 가지느냐도 중요한 문제이다.

max_width가 정의되어 있지 않으면 당연히 max_width는 false로 처리 되고, 그 이후 prefrenerces.max_width를 평가할 것이다.

하지만 max_width가 정의되어 있고 0이라는 값을 가지고 있을때는 어떻게 동작할 것인가? 당연히 0은 false로 처리 될 것이고, prefrernces.max_width을 확인해야 할 것이다. 그러므로 해당 설명을 정확하게 하려면 다음고 같이 바뀌어야 한다.


// max_width가 정의되어 있으면서 0 이 아니라면, 이것을 사용한다. 정의되어 있더라도 0 이라면 이것을 사용하지 않는다.




 97 페이지 두번째 예제


function copy(o, p) {

    p = p || {?};   // 만약 인자 p가 null이면, 새롭게 객체를 생성한다.

    // ...

}


function copy(o, p) {

    p = p || {};   // 만약 인자 p가 null이면, 새롭게 객체를 생성한다.

    // ...

}


로 ? 가 쓸데 없이 들어 있다.


전반적으로 ;; 소스코드 부분의 들여쓰기나, 띄워쓰기(코딩 컨벤션)가 일정하게 되어 있지 않다. 세미콜론 처리 역시 어떤 예제는 꼬박꼬박 넣고, 어떤 예제는 두 줄이상의 소스코드인데도, 넣었다(99페이지 마지막 예제) 안 넣었다(97페이지 마지막예제) 한다. 그래서 이런건 또 왠만해서는 생략.


빈객체나 빈 문배열등을 만들때 쓸데 없이 ? 가 들어 있는 경우가 많다. ? 에 대한 문제는 너무 많아서 이제 부터는 생략.

{?} 나 [?] (?) 등을 보시게 되면... ? 는 없는 것으로 생각하고 코드를 보시라.



자바 스크립트는 기본적으로 Type Checking이라던지, 각종 코드에 대한 검사를 덜 하는것으로 판단된다. 예를 들면 변수를 선언하지 않고도 바로 사용한다던지, 읽기 전용 속성인데도 값을 할당한다던지 하는것에 대해서 에러를 발생시키지 않는다. 

이러한 방식은 코드를 더 쉽게, 그리고 유연하게 만들 수 있는 장점이 있겠지만, 나 같은 사람들에게는 오히려 혼란을 가중 시키기도 한다. 이러한 문제를 해결 하기 위해서 "strict mode"라는 것을 지원한다. 이 기능을 켜 두게 되면, 자바 스크립트가 말 그대로 "엄격"한 검사를 통해서 실행된다. 


"엄격"하게 자바스크립트를 작성하고, 실행하고 싶다면 js 파일의 첫번째 줄에 "use strict"; 를 추가해 주면 된다. 특정 함수만 "엄격"하게 실행하고 싶다면 함수 구현의 첫번째 줄에 "use strict"; 라고 넣으면 된다. ( " 를 빼 먹지 말고 다 적어야 한다. ) - IE 10 미만 버젼에서는 사용할 수 없다고 한다.



"use strict";  // 이 선언으로 인해서 현재 js 파일은 엄격 모드로 실행되게 된다.


function a() {

    // ....

}



function b() { // 아래와 같이 특정 함수만 엄격 모드로 실행되게 할 수도 있다.

    "use strict";

    // .....

}





106페이지 delete연산자 6번째줄 부터 있는 예제


var o = { x:1, y:2 };

delete o.x;

"x" in o;


뜬금 없는 문법 오류로 보일 수 있지만 in 이라는 연산자가 있는 것이다. 

"PROPERTY_NAME" in OBJECT 의 형태로 사용할 수 있다.



106페이지 중간 즈음에 delete 연산자 설명중


delete 연산자의 피연산자는 좌변값(lvalue)이다. 피연산자가 좌변 값이 아니면 연산자는 아무런 동작을 하지 않고, true를 반환한다. 피연산자가 좌변값이면 연산자는 해당 좌변 값을 삭제하려고 시도하며, 피연산자가 성공적으로 삭데되었을 경우 true를 반환한다.


좌변값이라는 용어를 먼저 알아야 한다.


변수에 값을 할달 하는 경우 아래와 같이 코드를 작성한다.


var x = 10;


위 코드에서 = 를 기준으로 왼쪽에 있는 것을 좌변값(left-value,lvalue)라고 하고, 오른쪽에 있는것 우변값(right-value,rvalue)라고 한다. variable이 좌변 값이 된다. 즉, 어떤 값을 할당 할 수 있는것들이 lvalue가 되고, 이것들을 delete 시킬 수 있다는 것이다.


설명상 "delete 연산자의 피연산자는 좌변값(lvalue)이다." 라는것은, delete의 왼쪽에 있는 값이 피연산자라는것이 아니라, delete 다음에 올 수 있는 피연산자는 lvalue 형태의 것들만 올 수 있다는 의미이다.


그 아래쪽에도 나오지만, 정확하게 말하면 위의 코드에서 x를 delete 시킬 수는 없다. delete 시킬 수 있는것은 property 형태만 가능하다. 107페이지 첫번째 예제에서 this.x 에 값을 할당 한 뒤, 그냥 x를 delete 시킬 수는 없었지만, this.x 를 delete 시킬 수는 있게 된다.


107페이지, 110페이지


부수효과


계속해서 부수효과라는 용어가 등장한다. 부수효과라는 용어는 Side Effect라는 용어의 한국어 번역 단어로 많이 사용된다. 우리가 일반적으로 생각하는 Side Effect는 "예상치 못했던 문제 상황"을 뜻하는데, 여기서는 그렇지 않다.

여기서 말하는 부수효과를 쉽게 말하면, state 를 바꾸는것을 생각하면 된다. 아래의 코드를 보자


var x = 3;


위의 코드는 사실상 아무것도 하지 않는것으로 느껴지지만, x라는 변수를 생성하고 이 변수에 3을 할당한 코드이다. x의 state가 변경된 것이다. 이렇다면 이는 "부수효과가 있다"고 볼 수 있다. 하지만 다음 코드를 보자.


Math.cos(Math.PI);


위 코드는 PI 값으로 코사인 정보를 얻어왔지만, 아무곳에서 할당하지 않았다. 즉, state의 변화가 없다. 이 경우 "부수효과가 없다." 고 볼 수 있다.



 

 



 

 



 

 



 

 


+ Recent posts