tag: js

JavaScript 부분 어플리케이션

Partial Application in JavaScript 번역, 부분 어플리케이션의 개념

2015년 7월 13일

이상한모임 슬랙 #dev-frontend 채널에서 함수가 1급 시민이라는 얘기가 나온 적이 있었다. Wikipedia를 읽다가 Partial Application에 대한 이야기가 있어 검색하던 중 John Resig이 작성한 Partial Application in JavaScript를 읽게 되었다. 2008년 글이라 요즘 코드와는 조금 다른 부분이 있지만 개념을 잡기에는 충분히 도움이 되는 것 같아 번역했다.


면밀하게 보면, 부분만 사용한 함수는 함수가 실행되기 전에 미리 인자를 지정할 수 있는, 흥미로운 기법이다. 이와 같은 효과로 부분만 반영된 함수는 호출할 수 있는 새로운 함수를 반환한다. 다음 예제를 통해 이해할 수 있다:

String.prototype.csv = String.prototype.split.partial(/,\s*/);
var results = "John, Resig, Boston".csv();
alert( (results[1] == "Resig") + " The text values were split properly." );

위에서는 일반적으로 사용하는 String의 .split() 메소드에 인자로 미리 정규표현식을 저장하는 경우다. 그 결과로 만들어진 새로운 함수 .csv()를 쉼표로 분리된 값을 배열로 변환하는데 사용할 수 있다. 함수 인자를 앞에서부터 필요한 만큼 채우고 새로운 함수를 리턴하는 방식을, 일반적으로 커링(currying)이라 부른다. 간단하게 커링은 어떻게 구현되는지 다음 프로토타입 라이브러리에서 확인할 수 있다:

Function.prototype.curry = function() {
  var fn = this, args = Array.prototype.slice.call(arguments);
  return function() {
    return fn.apply(this, args.concat(
      Array.prototype.slice.call(arguments)));
  };
};

상태를 기억하기 위해 클로저(closure)를 사용한 좋은 케이스다. 이 경우에 미리 입력한 인수(args)를 저장하기 위해서 새로 만들어지는 함수에 전달되었다. 새로운 함수는 인수가 미리 입력되게 되고 새로운 인수도 하나로 합쳐져(concat) 전달된다. 그 결과, 이 메소드는 인수를 미리 입력할 수 있게 되고 활용 가능한 새 함수를 반환하게 된다.

이제 이 스타일의 부분 어플리케이션은 완전 유용하지만 더 좋게 만들 수 있다. 만약 주어진 함수에서 단순히 앞에서부터 인수를 입력할 것이 아니라 비어있는 모든 인수를 채우기 원한다면 어떻게 해야할까. 다음과 같은 형태의 부분 어플리케이션 구현은 다른 언어에도 존재하지만 JS에서는 Oliver Steele가 Function.js 라이브러리에서 시연했다. 다음 구현을 살펴보자:

Function.prototype.partial = function (){
  var fn = this, args = Array.prototype.slice.call(arguments);
  return function(){
    var arg = 0;
    for ( var i = 0; i < args.length && arg < arguments.length; i++)
      if ( args[i] === undefined )
        args[i] = arguments[arg++];
    return fn.apply(this, args);
  }
}

이 구현은 근본적으로 curry() 메소드와 비슷하지만 중요한 차이점이 존재한다. 특히 이 함수가 호출될 때, 미리 입력하고 싶지 않은 인수에 대해 undefined를 입력하는 것으로 나중에 입력하도록 만들 수 있다. 이 방식의 구현은 인수를 병합하는데 더 편리하게 활용할 수 있게 돕는다. 인수를 배정하는 과정에서 비어있는 곳에 적절한 간격으로 처리해 나중에 실행할 때 조각을 맞출 수 있게 만든다.

위에서 문자열 분리 함수를 생성하는데 사용한 예에도 있지만 다른 방식에서 어떻게 새 함수 기능을 활용할 수 있는지 확인하자. 함수를 간단하게 지연해서 실행하도록 하는 함수를 생성할 수 있다.

var delay = setTimeout.partial(undefined, 10);
delay(function(){
  alert( "A call to this function will be temporarily delayed." );
});

delay라는 이름의 새로운 함수를 만들었다. 언제든 함수를 인자로 넣으면 10ms 후에 비동기적으로 실행하게 된다.

이벤트를 연결(binding) 하기 위한, 간단한 함수를 만들 수 있다:

var bindClick = document.body.addEventListener
                  .partial('click', undefined, false);

bindClick(function() {
  alert( "Click event bound via curried function." );
});

이 기법은 라이브러리에서 이벤트를 연결하기 위해 사용하는, 간단한 헬퍼 메소드로 사용할 수 있다. 이 결과로 단순한 API를 제공해 최종 사용자가 불필요한 인수로 인해 번거롭게 되는 경우를 줄이고 단일 함수를 호출하는 횟수를 줄일 수 있다.

클로저를 사용하면 결과적으로 코드에서의 복잡도를 쉽고 간단하게 줄일 수 있어서 JavaScript 함수형 프로그래밍의 강력함을 확인하게 된다.

JavaScript로 Arduino 제어하기 Johnny-Five

JS의 다양한 라이브러리, 강력한 기능을 Arduino에서 활용하는 방법

2015년 6월 26일

요즘 출퇴근 하는 시간에는 눈도 쉴 겸 팟캐스트를 자주 듣는다. 그 중 Hanselminutes을 애청하고 있는데 Scott Hanselman이 여러 분야 사람들을 인터뷰하는 방식으로 진행되는 팟캐스트다. 이 팟캐스트에서 진행한 Getting started making NodeBots and Wearables 에피소드에서 NodeBots 프로젝트Johnny-Five.io에 대해 알게 되어 살펴보게 되었다.

NodeBots

NodeBots 프로젝트는 말 그대로 JavaScript를 이용해 로봇공학을 배우는 프로젝트로 세계 각지에서 진행되고 있다고 한다. JS를 사용할 수 있는 이점을 살려 쉽고 재미있는 과정을 제공하고 있는데 2015년 7월 25일은 국제 NodeBots의 날로 각 지역별로 프로그램이 진행된다.(멜번에서도!) 아쉽게도 한국에는 아직 오거나이저가 없는 것 같다.

Johnny-Five는

Johnny-Five는 JavaScript 로봇공학 프로그래밍 프레임워크로, 이전 포스트인 ino toolkit으로 Arduino 맛보기에서 C 문법 스타일의 sketch를 사용한 반면 이 프레임워크로 JavaScript를 이용해 제어할 수 있다. 그리고 REPL을 제공하고 있어서 실시간으로 데이터를 확인하거나 nodejs의 다양한 라이브러리도 활용할 수 있다. NodeBots 세션에서는 손쉽게 웹API로 만들어 브라우저를 통해 제어하는 등 이전 환경에서는 만들기 까다로웠던 부분을 재미있게 풀어가는데 활용하고 있다. 게다가 이 프레임워크는 아두이노에만 국한된 것이 아니라 다양한 개발 보드를 지원하고 있는 것도 장점이다.

그 사이 주문한 서보 모터는 도착했는데 서보 실드나 브래드보드가 도착하지 않아서 여전히 LED 깜빡이는 수준이라 아쉽다. 🙁 이 포스트에서는 Raspberry Pi에 Arduino Uno를 연결해서 진행했다.

요구 환경

OSX에서는 Node.js, Xcode, node-gyp가 필요하고 Windows에서는 Node.js, VS Express, Python 2.7, node-gyp가 필요하다.

$ npm install --global node-gyp

요구 사항은 Getting Started 페이지에서 확인할 수 있다.

Firmata 설치하기

Arduino에서 Johnny-Five를 사용하기 위해서는 Firmata를 먼저 설치해야 한다. Firmata는 마이크로 컨트롤러를 소프트웨어로 조작하기 위한 프로토콜인데 펌웨어 형태로 제공되고 있어 arduino에 설치하기만 하면 된다.

Arduino IDE를 사용하고 있다면 아두이노를 연결한 후, File > Examples > Firmata > StandardFirmata 순으로 선택한 후 Upload 버튼을 클릭하면 된다고 한다.

CLI 환경에서 작업하고 있는 경우에는 Firmata 코드를 받아 ino로 빌드 후 업로드할 수 있다. 여기서는 v2.4.3 이지만 Firmata github에서 최신인지 확인하자.

$ wget https://github.com/firmata/arduino/releases/download/v2.4.3/Arduino-1.6.x-Firmata-2.4.3.zip
$ unzip Arduino-1.6.x-Firmata-2.4.3.zip
$ cd ./Firmata/

# StandardFirmata.ino를 복사해서 빌드에 포함시킴
$ cp ./examples/StandardFirmata/StandardFirmata.ino ./src

이 상황에서 바로 빌드하면 에러가 난다. StandardFirmata.ino를 에디터로 열어 다음 코드를 찾는다.

#include <Firmata.h>

그리고 다음처럼 Firmata.h 파일을 폴더 내에서 찾도록 수정한다.

#include "./Firmata.h"

모든 준비가 끝났다. USB로 연결한 후, ino로 빌드와 업로드를 진행한다.

$ ino build
$ ino upload

Firmware를 생성하고 업로드하는 과정을 화면에서 바로 확인할 수 있다. 이제 Johnny-five를 시작하기 위한 준비가 끝났다.

Johnny-five로 LED 깜빡이 만들기

앞서 과정은 좀 복잡했지만 johnny-five를 사용하는건 정말 간단하다. 먼저 nodejs가 설치되어 있어야 한다. 프로젝트를 만들고 johnny-five를 npm으로 설치한다.

$ mkdir helloBlinkWorld
$ cd helloBlinkWorld
$ npm init # 프로젝트 정보를 입력
$ npm install --save johnny-five

설치가 모두 완료되면 blink.js를 생성해 다음 JavaScript 코드를 입력한다.

var five = require("johnny-five"),
    board = new five.Board();

board.on("ready", function () {

  // 13은 보드에 설치된 LED 핀 번호
  var led = new five.Led(13);

  // 500ms으로 깜빡임
  led.blink(500);

});

정말 js다운 코드다. 위 파일을 저장하고 node로 실행하면 보드와 연동되는 것을 확인할 수 있다. (아쉽게도 동영상은 만들지 않았다 🙂 더 재미있는 예제를 기약하며)

$ node blink.js

JavaScript가 다양한 영역에서 사용되고 있다는 사실은 여전히 신기하다. 이 프레임워크도 상당히 세세하게 많이 구현되어 있어서 단순히 JS 로보틱스 입문 이상으로도 충분히 활용할 수 있겠다는 인상을 받았다. 조만간 Tessel 2도 나올 예정인데 이 기기의 js 사랑도 이 라이브러리와 견줄만 할 정도라 많이 기대된다.

ECMAScript 6를 위한 Babel 기본 사용법

JavaScript의 최신 문법, ECMAScript 6가 적용되기 전에 사용해볼 수 있는 방법

2015년 6월 7일

ECMAScript 6 에서 추가되는 많은 새로운 기능들이 기대가 되면서도 아직까지 직접 사용해보지 못했었다. 최근에 JavaScript 관련 컨퍼런스 영상 뿐만 아니라 대부분의 포스트도 최신 문법으로 작성되는 경우가 많아 살펴보게 되었다.

ES5 표준은 2009년에 표준화되어 점진적으로 반영되고 있지만 ECMAScript 6는 2015년 6월 승인을 목표로 작성되고 있는 새 ECMAScript 표준이다. Prototype 기반의 객체 지향 패턴을 쉽게 사용할 수 있도록 돕는 class의 추가, => 화살표 함수 표현, 템플릿 문자열, generatoryield 등 다른 언어에서 편리하게 사용하던 많은 기능들이 추가될 예정이다.

현재 나와있는 JS 엔진에는 극히 일부만 실험적으로 적용되어 있어서 실제로 사용하게 될 시점은 까마득한 미래와 같이 느껴진다. 하지만 현재에도 기존 JavaScript와 다른 문법을 사용할 수 있도록 돕는 transform compiler가 존재한다.

TypeScript, CoffeeScript는 JavaScript 문법이 아닌 각각의 문법으로 작성된 코드를 JavaScript에서 동작 가능한 코드로 변환한다. 이와 같은 원리로 ECMAScript 6 문법으로 작성된 파일을 변환-컴파일하는 구현이 존재한다. 이 포스트에서 소개하려는 라이브러리, babel이 바로 그 transcompiler 중 하나다.

Babel 사용하기

다른 라이브러리와 같이 npm으로 설치 가능하다.

$ npm install --global babel

ES6로 작성한 파일로 js 컴파일한 결과를 확인하려면 다음 명령어를 사용할 수 있다.

$ babel script.js

파일로 저장하기 위해 --out-file, 변경할 때마다 저장하도록 하려면 --watch 플래그를 활용할 수 있다. 파일 대신 경로도 사용할 수 있다.

$ babel ./src --watch --out-file script-compiled.js

babel을 설치하면 node.js의 CLI와 같이 사용할 수 있는 babel-node 라는 CLI를 제공한다. node처럼 REPL나 직접 파일을 실행할 때 사용할 수 있다. 직접 실행해서 확인할 때 편리하다.

$ babel-node # REPL 실행 시
$ babel-node app.js

자세한 내용은 babel CLI 문서에서 확인할 수 있다.

다른 도구와 함께 Babel 사용하기

Babel은 다양한 usage에 대한 예시를 제공하고 있다. Babel의 Using Babel을 확인하면 현재 사용하고 있는 도구에 쉽게 접목할 수 있다.

Meteor는 다음 패키지를 설치하면 바로 사용할 수 있다. 이 패키지를 설치하면 .es6.js, .es6, .es, .jsx 파일을 자동으로 컴파일 한다.

$ meteor add grigio:babel

Webpack을 사용하고 있다면 babel-loader를 설치한 후 webpack.config.js에 해당 loader를 사용하도록 설정하면 끝난다.

Webpack을 사용해보지 않았다면 다음 순서대로 시작할 수 있다. Webpack은 모듈을 하나의 파일로 묶어주는 module bundler의 역할을 하는 도구다. 먼저 CLI를 설치한다.

$ npm install --global webpack

프로젝트에서 babel을 사용할 수 있도록 babel-loader를 추가한다.

$ npm install babel-loader --save-dev

webpack.config.js 파일을 다음과 같이 작성한다.

module.exports = {
  entry: "./app.js",
  output: {
    path: __dirname,
    filename: "bundle.js"
  },
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
    ]
  }
}

위 설정은 node_modules 디렉토리를 제외한, 프로젝트 내에 있는 모든 *.js를 babel로 변환 후 묶어준다. 각각 세부적인 옵션은 webpack 문서에서 살펴볼 수 있다.


매번 비슷하면서도 전혀 새로운 라이브러리가 많이 나와 때로는 따라가기 버겁다는 생각이 들 때도 있지만 찬찬히 들여다보면 그 새로움에 자극을 받게 된다. (부지런한 사람들 같으니!) 다음 세대 ECMAScript를 준비하는 마음으로 새로운 문법도 꼼꼼히 봐야겠다. Babel, Webpack 등 최근 나오는 라이브러리는 문서화가 잘 되어있는 편이라 금방 배우기 쉬운 편이니 각 문서를 확인해보자.

더 읽을 거리

MelbJS 5월 모임 참석 후기

2015년 5월, 멜번 javascript 정기 모임 melbjs에 다녀온 이야기

2015년 6월 5일

5월은 여러가지 일이 있어 참 바빴던 달이라 이제서야 후기를 적는다. MelbJS은 매달 정기적으로 열리는 멜번 JavaScript 밋업이다. 멜번에서도 다양한 밋업이 정기적으로 열리고 있는데다 한결 같이 흥미로운 주제라 자주 가고 싶지만 끝나고 집에 가는 것이 애매해서 1년에 두어 번 정도 가지 못할 뿐더러 가더라도 막차를 타야해서 앞 세션만 듣고 나와야 하는 아쉬움이 늘 있다. 관심있는 주제도 있고 새로운 자극도 받을 겸 시간내서 참가했다.

Aconex 1

밋업은 매월 Aconex 오피스에서 진행하고 있다. 식당 공간을 다용도로 사용할 수 있도록 잘 만들어둬서 올 때마다 사무실이 생기면 꼭 이렇게 공간을 꾸며야겠다는 생각이 든다. 벽 한 켠은 칠판으로 만들어 둬 현재 이 회사에서 진행중인 프로젝트를 힐끔 살펴볼 수도 있다. (밋업을 가면 분위기라는게 있는데 Python 밋업은 학구적인 모임, JS 밋업은 힙스터 모임, .Net 밋업은 제2의 회사로 출근한 분위기다. 흐흐.) 스폰서가 많아 생맥주에, 피자에, 장소까지 풍성하다. 음식을 제공하는 행사마다 채식, 할랄 푸드를 먹는 사람을 위한 메뉴를 두는 모습이 참 보기 좋다.

Smarter CSS Builds with Webpack

envato의 개발자인 Ben Smithett의 세션이었는데 Webpack을 이용해서 CSS를 패키징하는 방법을 보여줬다. 패키징 자체는 크게 새로운 얘기가 아니었지만 컴포넌트 단위의 개발에서 CSS를 편리하게 적용할 수 있는 방법을 제시했다. 어플리케이션에서 실제로 필요하지 않은 CSS까지 전부 불러오는 것이 아니라 컴포넌트에서 필요한 CSS만 불러오는 형태로 작성해, 컴포넌트 단위 구성을 스타일까지 확장할 수 있게 된다.

물론 컴포넌트 단위로 사용하려고 하면 CSS도 컴포넌트 단위에 맞는 접근이 필요하다. CSS pre-compiler를 사용하게 되면 변수의 scope가 전역적으로 다뤄지기 마련이라 각 컴포넌트를 독립적인 css로 관리하는데 불편함이 있는데 각각 독립된 컴포넌트에서 필요한 변수셋을 불러오는 형태로 그 의존성을 분산할 수 있다.

컴포넌트를 더 컴포넌트답게 활용할 수 있게 하는 아이디어라서 더욱 마음에 들었던 세션이었다. react로 개발하고 있다면 살펴볼 만한 좋은 주제다. 전체 세션의 내용은 Ben Smithett의 블로그 포스트에서 확인할 수 있다.

React Native — One of these things is not like the other

Matt Delves의 세션으로 react native에 대한 전반적인 이야기를 다뤘다. 이전에 공식 문서 튜토리얼을 살펴봤을 때랑 많이 달라지지 않아 크게 새로운 이야기는 없었지만 flux 아키텍쳐에 대해 알게된 후 듣는 react native라서 기분이 새로웠다. 세션 중간에 Colin Eberhardt를 인용했는데 react에 대해 정확하게 표현하는 느낌이다.

“React는 사용자 인터페이스를 생성하는데 독창적이며 급진적인, 고수준의 함수형 접근을 도입했다. 간단히 말해, 어플리케이션의 UI는 단순히 현재 어플리케이션의 상태를 표현하는 함수 역할을 한다.”

“React introduces a novel, radical and highly functional approach to constructing user interfaces. In brief, the application UI is simply expressed as a function of the current application state.”

아직 구현되지 않은 view도 많고 부족한 부분이 있지만 계속 개선되고 있어서 더욱 더 기대되는 라이브러리다. 전체 발표 내용은 GitHub Repo.에 올려져 있다.

Aconex 2

요즘 쏟아지는 수많은 라이브러리를 다 써보지 못해서 늘 아쉬운 기분이 든다. 실무에서 사용하지 않고 있다면 개인 프로젝트로라도 진행해서 써봐야 이해도 되고 손에도 익는데 무언가 만들고 싶은 욕구가 덜해서 고민이 많다. 아무리 바쁘더라도 한 발자국 물러나면 별 일도 아닌 일인 경우가 너무나도 많은데 쉽지 않다. 여유를 다시 찾고 다시 재미있게 코드를 만들 수 있었으면 좋겠다.

자바스크립트 스터디 – Chapter 4 정리

2014년 4월 8일

다른 프로그래밍 언어와 같은 부분이 많아 큰 어려움은 없었지만 타입 변환 등 자바스크립트만의 특성으로 잘 읽어봐야 할 부분이 많았다. 특히 typeofinstanceof 부분은 JavaScript를 더 이해하는데 도움이 되었다.


Chapter 4 표현식과 연산자 Expressions and Operators

표현식 : 값을 구하기 위한 표현 방법

연산자 : 표현식의 구성요소 (값을 반환하거나 연산함)

4.1 Primary Expressions

상수, 문자열 값, 키워드, 변수 레퍼런스 (eg. true, false, undefined)

4.2 객체, 배열 생성자 Object and Array Initializers

  • 객체 : {}
  • 배열 : []

4.3 함수 정의 표현식

var square = function(x) { return x * x; };

4.4 프로퍼티 접근 표현식

expression.identifier  // 식별자가 이렇게 써도 문법에 위배되지 않을 때 사용 가능
expression[expression] // 배열일 때 특히

4.5 구동 표현식 Invocation Expressions

square(10)
Math.min(x, y, z)
foos.sort()
  • 아규먼트의 연산을 먼저 한 후 함수가 실행됨 (in common sense)
  • 실행 가능 객체가 아니라면 TypeError
  • return
  • 함수(OO에선 메서드)가 실행될 때 this

4.6 객체 생성 표현식

var o = new Object()
var d = new Date()
  • 초기화 할 때 생성되는 this

4.7 연산자 미리보기

  • p.62 표 참조. 다른 프로그래밍 언어랑 크게 다른게 없음.
  • typeof, instanceof
  • 문자열 합칠 때와 숫자 계산할 때 둘 다 + 사용
  • 형변환이 자유롭게 발생하므로 유의 "3" * "5" // => 15

4.8 산술 표현식 Arithmetic Expressions

  • *, /, %, +, –
  • NaN
    • 연산자 : 값을 합칠 때 해당 값이 객체이면 3.8.3에서 본 것처럼 toString() 또는 valueOf()로 형변환 시도
  • 비트연산자 : &, |, ^, ~, <<, >>, >>>

4.9 관계 표현식 Relational Expressions

  • ===== : 타입 변환 허용 var point = { x : 10, y: 20 };

    “x” in point // => true

    “s” in point // => false

    var data = [3, 2, 1];

    “0” in data // => true

    // 배열은 값이 들어 있는지 확인하는 것이 아니라 해당 index에 값이 있는지 확인해줌

  • instanceof : 어떤 클래스인지 확인할 때. 상속되는 모든 클래스에 대해 true

4.10 논리 표현식

  • &&, ||, !

4.11 배정 표현식 Assignment Expressions

  • =, +=, -=, *=, /=, %=, <<=, >>=, >>>=, &=, |=, ^=

4.12 평가 표현식 Evaluation Expressions

  • eval(): 하나의 아규먼트를 js 코드처럼 처리해줌.
  • ES5에서 global eval
  • IE 전용 execScript()

4.13 그 외 표현식

  • 3항 연산자(?:) : var age = birthyear > 2000 ? "yong" : "old";
  • typeof : p.82 표 참조
    • “undefined”, “object”, “boolean”, “number”, “string”, “function”, “object”, “<구현한 객체>”
    • null"object" 반환
    • 호출 가능한 객체 callable object 가 정확하게 함수function는 아님. 하지만 typeof에서는 호출 가능한 객체에 대해 “function”을 반환
  • delete
    • ES5 strict에선 못지울 것 지우면 SyntaxError
    • garbage collection이 있으므로 일일이 지워줄 필요는 없음
  • void : 프로토콜에서 사용하는데 (주. 쓰지말자.)
  • , : a=1, b=2, c=3;

자바스크립트 스터디 – Chapter 3 정리

2014년 4월 2일

짧지 않았던 3번째 챕터인데 깊은 내용은 후반부에 다룬다는 부분이 많았다. 전반적으로 살펴보는 느낌으로 읽으면 좋을 것 같다.


Chapter 3 타입1, 값, 변수 Types, Values, and Variables

이 챕터에서는 다음 세가지에 대해 심층적인 설명을 다룸.

  • 타입 : 문자열, 숫자, 객체 등 값이 어떤 형태의 자료인지를 의미
  • 값 : 3.14, “Hello World” 실제 저장되는 정보
  • 변수 : 값을 나중에 사용하기 위해 이름으로 저장해두는 공간

3.1 숫자

64비트 부동 소수점 포맷

  • 정수 문자열 : 10진수(255), 16진수(0xff), 8진수(0377)
  • 부동 소수점 문자열 : [digits][.digits][(E|e)[(+|-)]digits]
  • 계산 : +, -, *, /, % and Math object (p.33)
  • 무한대 : -Infinity, Infinity, negative 0 (but 0 == -0 => true)
  • NaN : Not-a-number value. 0으로 나누기 등 에러가 발생하는 계산에서 나타나는 값 (비교연산자 못씀. isNaN())
  • 다른 프로그래밍 언어처럼 부동 소수점 처리에 문제가 있으므로 정수 영역으로 쓸 것
  • 일자와 시간 : Date object (p.35), new Date().getTime(). 숫자처럼 비교 가능한 객체

3.2 텍스트

  • 불변(배열같이 0부터 인덱싱), 16비트, 유니코드
  • ” 또는 “”, 개행 또는 이스케이프 시 \ 사용 (p.37, 38)
  • 텍스트 메소드 p.38~
  • 정규표현식 : /hello/g.test("hello world") (챕터 10)

3.3 불린값 Boolean Values

  • true 또는 false
  • undefined, null, ``, -0, NaN, "" => false

3.4 nullundefined

  • undefined : 시스템 레벨, 예측할 수 없어서 마치 에러같은 빈 값, TypeError
  • null : 프로그램 레벨, 일반적 또는 예측 가능한 형태로의 빈 값, no object as an object
  • ==로는 같으나(false이므로) ===로는 다름

3.5 전역객체 The Global Object

JavaScript 해석기(interpreter)가 실행될 때 선언됨 (새로고침하거나.. 할 때 항상)

  • 전역 프로퍼티 : undefined, Infinity, NaN
  • 전역 함수 : isNaN(), parseInt(), eval()
  • 생성자 함수 : Date(), RegExp(), String(), Object()
  • 전역 객체 : Math, JSON

웹브라우저에서는 window, 콘솔에서는 global

3.6 레퍼 객체 Wrapper Objects

기본형 primitive value인 경우 프로퍼티를 가질 수 없으므로 그런 경우 레퍼 객체를 활용할 수 있음. OO로 개발할 때 도움. (Java의 레퍼 클래스와 비슷한듯)

var s = "test", d = new String("test");
s.len = 4, d.len = 4;
console.log(s.len, d.len); // undefined 4
  • String(), Number(), Boolean()

3.7 변하지 않는 기본형과 변하는 객체 참조 Immutable Primitive Values and Mutable Object

References

  • 기본형과 객체의 기본적인 차이인 불변성. 객체는 값이 아닌 참조가 들어있기 때문.
  • 객체를 비교하거나 복사할 때는 유의해야 함. (비교 코드 예시 p.45)

3.8 타입 변환

JavaScript에서의 타입 변환은 완전 유연

  • true로 변하는 값, false로 변하는 값

  • 타입 변환 표 p. 46

  • 비교할 때 타입 변환을 고려할지 안할지. ==, ===

  • 명시적 변환 : 레퍼 객체 또는 x + "", +x",!!x` 활용

  • 진수 변환, 정수 또는 소수 등 parsing parseInt(), (320.329).toFixed(2)

  • 3.8.3 객체를 기본형으로 변환 : valueOf() => toString() => TypeError

  • 객체-숫자 변환과 객체-텍스트 변환 두가지로 문제 발생할 수 있음 typeof(new Date() + 1) // => “string”

    typeof(new Date() – 1) // => “number”

    typeof(+new Date() + 1) // => “number”

3.9 변수 선언

  • var로 선언 : 타입이 따로 지정되지 않음.
  • 중복 선언해도 에러 발생 안함. 선언 안하면 에러남.
  • 항상 var 사용하는걸 권장. => 3.10.2

3.10 변수 스코프 Variable Scope

  • 프로그램 소스코드에서 선언한 변수를 사용할 수 있는 범위. 전역 변수는 전역 스코프를 가짐.

  • 함수 스코프와 호이스팅 Hoisting

    — C에서는 { } 기준의 block scope지만 js에서는 함수 기준의 스코프

    — 함수 중간에 var로 변수선언이 있으면 함수 실행 시 처음에 다 선언처리함 (hoisted)

  • 프로퍼티로서의 변수 : var로 선언하면 삭제 불가능한 프로퍼티로 생성

  • 스코프 체인

    — 변수 확인할 때 스코프 내에 선언되지 않은 경우 상위 스코프로 계속 이동하며 찾음. 끝까지 없으면 ReferenceError

    — 함수 내에 함수를 선언 했을 때

    with 5.7.1, 클로저의 이해 8.6 참고

  • 프로그래밍 서적에서는 흔히 type을 형으로 번역하는데 그냥 영어로 적는다.