oinume journal

Scratchpad of what I learned

JavaScriptの記号の演算子と構文

JavaScript / TypeScript では一見すると「これなんだ?」という記号の演算子や構文がよく出てくるので、自分用の備忘録としてメモしておく。式と演算子 - JavaScript | MDNには演算子の一覧のページがあるため、わからない記号が出てきたら以下のページを見るとだいたい載っているはず。

?? - Nullish coalescing operator

  • Null 合体 (??) - JavaScript | MDN
  • Null 合体演算子 (??) は論理演算子の一種です。この演算子は左辺が null または undefined の場合に右の値を返し、それ以外の場合に左の値を返します。
  • 例えば以下のコードだと、aがnull or undefinedの場合は a is null or undefined がvalに代入される
const val = a ?? 'a is null or undefined';

!! - Double not operator

  • Logical NOT (!) - JavaScript | MDN
  • 複数の否定演算子を連続して使用することで、明示的にあらゆる値を対応する論理型プリミティブに変換することができます。
  • 否定の否定なので肯定ということになり、元の値をbooleanに変換するということらしい
const val = !!a; // val is always boolean

?. - Optional chaining operator

  • オプショナルチェーン (?.) - JavaScript | MDN
  • ?. 演算子の機能は . チェーン演算子と似ていますが、参照が nullish (null または undefined) の場合にエラーとなるのではなく、式が短絡され undefined が返されるところが異なります。関数呼び出しで使用すると、与えられた関数が存在しない場合、 undefined を返します。
const val = a?.b?.c; // aがnull or undefinedの場合 val が undefinedになる

... - Spread syntax

  • スプレッド構文 - JavaScript | MDN
  • スプレッド構文 (...) を使うと、配列式や文字列などの反復可能オブジェクトを、0 個以上の引数 (関数呼び出しの場合) や要素 (配列リテラルの場合) を期待された場所で展開したり、オブジェクト式を、0 個以上のキーと値のペア (オブジェクトリテラルの場合) を期待された場所で展開したりすることができます。
  • 一番多用されるのは配列やオブジェクトをコピーするときなのではないかと思われる
const arr = [1, 2, 3];
const arr2 = [...arr]; // arr.slice()みたいな

! - Non-null assertion operator

これはJavaScriptではなくてTypeScriptにしかない演算子。

// Compiled with --strictNullChecks
function validateEntity(e?: Entity) {
  // Throw exception if e is null or invalid entity
}

function processEntity(e?: Entity) {
  validateEntity(e);
  let s = e!.name; // Assert that e is non-null and access name
}

TypeScriptのDestructuring assignment

最近仕事でfrontendの開発を少しずつやるようになったのだけど、TypeScriptはGoに比べて演算子や記号を使う記法が多くて読むのに一苦労する。なので「これなんだろう?」と思ったやつをメモしておく。

TypeScriptやっていて一番最初に「ん?」と思ったのは、以下のような構文だった。

const obj = { title: 'hello' }
const  { title: myTitle } = obj // ★
console.log(myTitle) // "hello"

★のコードでは

  1. obj というオブジェクトから title という要素を取り出して
  2. myTitleという定数を宣言
  3. myTitleに 1. で取り出した要素を代入する

ということをやっている。myTitleが定数宣言であるのに対して、キーのtitleは単純にオブジェクトのキーなので特に何かが宣言されているわけでない、ということが初めはわかっていなかったのでこの構文を見るたびに頭が混乱していた。

調べてみると、これはJS由来の構文でDestructuring assignmentと呼ぶらしい。

上の例ではオブジェクトから要素を取り出す例だったが、当然配列から特定の要素を取り出すこともできる。

const array = [1, 2]
const [ first, second ] = array
console.log(first) // 1

さらにスプレッド構文 ... を使って以下のような代入も可能。

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest); [30, 40, 50] 

Goと違って多値が返せないからこういう構文が必要になるのかなと思ったのだけど、どうなんだろう?

webpackで<script>タグでロードしたライブラリをbundleされたJSから外したい

webpackのconfigには externals というものがある(ドキュメント)。このexternalsで定義したライブラリは、importで参照していてもwebpackでビルドして生成される成果物(bundle.js)には含まれなくなるというもの。

自分のユースケース

  • もともとReactを使っていないプロジェクトで一部のページだけでReactを使っていきたい
  • 全ページでReactを使うわけではないので、bundle.js には含めたくない(サイズ削減)
  • Reactが必要なページのみHTML上の <script> タグでロード

webpack.config.js

externalsでreactを除外するよ、ということを定義すれば bundle.js には含まれないようになる。webpackの設定ファイルはこんな感じ。

const config = {
  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM',
  },
  ...
};

module.exports = config;

Making an enviroment to learn ES6 with babel

This is a just memo for me who is a beginner of front-end development.

First of all, install nodejs v4.4.0.

$ brew install homebrew/versions/node4-lts
$ node -v
v4.4.0

Put package.json into a current directory. DO NOT forget to add babel-preset-es2015.

{
  "name": "hello",
  "version": "1.0.0",
  "engines": {
    "node": "4.4.0",
    "npm": "3.8.2"
  },
  "devDependencies": {
    "babel-cli": "^6.0.0",
    "babel-preset-es2015": "^6.6.0"
  }
}

Run npm install

$ npm install 

Put .babelrc to tell babel using es2015 preset.

echo '{ "presets": ["es2015"] }' > .babelrc

Put hello.js.

"use strict";

class Hello {
    say(message) {
        console.log(message);
    }
}

new Hello().say("hello");

Transpile hello.js and run it.

$ node_modules/.bin/babel hello.js | node
hello

YUI Compressorを使ってWordPressのjsファイルを圧縮する

Webサイト高速化の手法の一つとして、Steve Souders さんが唱えている"Minify JavaScript and CSS" (JavaScriptCSSを圧縮せよ) というのがあります。若干今更感がありますが、ちょっとでも高速化するために、このブログで使用しているiNoveテーマのJSファイルをYUI Compressorを使って圧縮してみました。

 

YUI Compressorのインストール

例によってUbuntu 8.10な環境ですが、YUI CompressorはJava製なのでJDK 6.0を入れます。

 

$ sudo aptitude install sun-java6-jdk

 

終わったらYUI Compressorをダウンロードして解凍します(以後、解凍してできたディレクトリを$YUI_ROOTとします)。

 

WordPressのiNoveテーマで使っているJavaScriptファイルを圧縮

試しにこのブログで使用しているテーマiNoveのJavaScriptYUI Compressorを使って圧縮してみます。

 

$ cd ~/tech/wp-content/themes/inove/js/

$ java -jar $YUI_ROOT/build/yuicompressor-2.4.2.jar menu.js > menu.js.new

 

 

結果は標準出力に書き出されるので、適当に別ファイルにでもリダイレクトします(-o でもOK)。出来上がったファイルのサイズを見てみると、下記のように5.8KBのファイルが4.0KBに減っているのがわかります。(約68%になりました)

 

$ ls -lh menu.js*

-rw-r--r-- 1 kazuhiro kazuhiro 5.8K 2009-02-13 00:21 menu.js

-rw-rw-r-- 1 kazuhiro kazuhiro 4.0K 2009-02-13 00:23 menu.js.new

 

こうやってどんどんファイルを小さくしていけば、クライアントの.jsファイルの取得が速くなるのでサイトの高速化が見込めます。どのぐらい速くなるかはクライアントの海鮮速度に大きく依存するので一概には言えませんが、ガンガン圧縮して試してみると良いと思います。

 

[tmkm-amazon]487311361X[/tmkm-amazon]