# の前提条件

これらの記事は、three.jsの使用方法を学習するためものです。 JavaScriptのプログラミング方法を把握してる事を前提とします。 DOMとは何か、HTMLの記述方法、JavaScriptでDOMの作成方法を把握してる事を前提とします。 es6 modules のimportや `<script type="module">` タグを把握してる事を前提とします。 CSSや CSSセレクター が何か把握してる事を前提とします。 ES5、ES6、およびES7を把握してる事を前提とします。 イベントとコールバックでJavaScripが実行されるのを把握してる事を前提とします。 クロージャとは何かを知っている事を前提とします。

また、以下に簡単な復習と注意事項があります。

## es6モジュール

es6モジュールはスクリプトの中で `import` キーワード、または `<script type="module">` タグを使用してインラインでロードできます。 以下に両方の使用​​例があります。

    <script type="module">
    import * as THREE from 'three';

    ...

    </script>

パスは絶対パス、または相対パスでなければなりません。相対パスは常に `./` または `../` で始まり `<img>` や `<a>` などの他のタグやcss参照とは異なります。

詳細はこの記事の最後に記載しています。

## `document.querySelector` と `document.querySelectorAll`

`document.querySelector` を使用し、CSSセレクターに一致する最初の要素を選択できます。 `document.querySelectorAll` は、CSSセレクターに一致するすべての要素を返します。

## `onbody` は必要ありません

20年前の古いWebページでは、以下のようなHTMLが多く使われてました。

    <body onload="somefunction()">

このスタイルは非推奨です。スクリプトをページの下部に配置します。

    <html>
      <head>
        ...
      </head>
      <body>
         ...
      </body>
      <script>
        // inline javascript
      </script>
    </html>

または、deferプロパティを使用します。

## クロージャーの仕組みを知る

    function a(v) {
      const foo = v;
      return function() {
         return foo;
      };
    }

    const f = a(123);
    const g = a(456);
    console.log(f());  // prints 123
    console.log(g());  // prints 456

上記のコードでは、新しい関数が作成される度に関数 `a` を呼び出します。 その関数は変数 `foo` を 閉じ込めます 。 ここに詳細な情報 があります。

## `this` がどのように機能するか知る

`this` は魔法ではありません。 引数が関数に渡されるのと同じように、関数に自動的に渡される実質的な変数です。 簡単に説明すると、次のような関数を直接呼び出す場合です。

    somefunction(a, b, c);

`this` は `null`（strictモードまたはモジュールの場合）になりますが、ドット演算子を使用して関数を呼び出す場合と同様です。

    someobject.somefunction(a, b, c);

`this` は `someobject` がセットされます。

この部分はみなさんが混乱するコールバックです。

     const callback = someobject.somefunction;
     loader.load(callback);

これは経験の浅い人が期待するように動作しません。 なぜなら `loader.load` がコールバックを呼び出す時、`.` 演算子で `this` を呼び出していないため、デフォルトではnullになります（ローダーが明示的に何かを設定しない限り） コールバックが発生した時に `this` を `someobject` したい場合は、関数をバインドする必要があります。

     const callback = someobject.somefunction.bind(someobject);
     loader.load(callback);

この記事は `this` を理解するのに役立つかもしれません.

## ES5/ES6/ES7 stuff

### `var` は非推奨です。 `const` か `let` を使って下さい

`var` は使用する理由がありません。varを使用するのは悪い習慣と見なされます。ほとんどの場合、変数の値を変えない場合は `const` を使用します。 値が変更される場合は `let` を使用します。これにより大量のバグを回避できます。

### `for of` を使用し `for in` は使用しない

`for of` は新しい書き方で、 `for in` は古い書き方です。 `for in` で解決できない問題を `for of` が解決しています。 解決した一例として、オブジェクトのすべてのkey/valueのペアを反復処理ができます。

    for (const [key, value] of Object.entries(someObject)) {
      console.log(key, value);
    }

### `forEach` 、`map` 、 `filter` は役に立ちます

配列の関数である `forEach` や `map` 、 `filter` はモダンなJavaScriptで広く使われています。

### 分割代入を使う

`const dims = {width: 300, height: 150}` のObjectがあるとします。

古いコードの場合

     const width = dims.width;
     const height = dims.height;

新しいコードの場合

     const {width, height} = dims;

### オブジェクト宣言のショートカットを使う

古いコードの場合

     const width = 300;
     const height = 150;
     const obj = {
       width: width,
       height: height,
       area: function() {
         return this.width * this.height
       },
     };

新しいコードの場合

     const width = 300;
     const height = 150;
     const obj = {
       width,
       height,
       area() {
         return this.width * this.height;
       },
     };

### スプレット演算子 `...` を使う

スプレット演算子にはたくさんの使い方があります。例えば

     function log(className, ...args) {
       const elem = document.createElement('div');
       elem.className = className;
       elem.textContent = [...args].join(' ');
       document.body.appendChild(elem);
     }

もう1つの例

    const position = [1, 2, 3];
    somemesh.position.set(...position);

### `class` を使う

ES5より以前のオブジェクトのようなクラス構文は、ほとんどのプログラマーにはなじみがありませんでした。 ES5以降では、C ++やC＃、Javaのスタイルに近い`class` キーワードを使用 できるようになりました。

### gettersとsettersを理解する

Getters と setters は ほとんどのモダンなプログラミン言語でよく使われます。 ES5のクラス構文により、ES5以前よりもはるかに簡単に使えます。

### 必要に応じてアロー関数を使います

アロー関数はcallbackとPromiseで特に役立ちます。

    loader.load((texture) => {
      // use texture
    });

アロー関数は `this` をバインドします。

    const foo = (args) => {/* code */};

ショートカットで書くなら

    const foo = (function(args) {/* code */}).bind(this));

### Promiseはasync/awaitと同様です

Promisesは非同期な処理を助ます。Async/awaitはpromiseを助けます。

ここで扱うには大きな話題になるため、promiseのドキュメントを読んで下さい。 また、async/awaitもドキュメントを読んで下さい。

### テンプレートリテラルを使用する

テンプレートリテラルは、引用符（"", ''）の代わりにバックティック文字（`` ）を使います。

    const foo = `this is a template literal`;

テンプレートリテラルには基本的に2つの機能があります。1つは複数行にかけます。

    const foo = `this
    is
    a
    template
    literal`;
    const bar = "this\nis\na\ntemplate\nliteral";

上記の `foo` と `bar` は同様の意味になります.

もう1つは、文字モードの中に `${javascript-expression}` のようにJavaScriptのスニペッドを挿入できます。 これはテンプレートの一部です。例えば

    const r = 192;
    const g = 255;
    const b = 64;
    const rgbCSSColor = `rgb(${r},${g},${b})`;

または

    const color = [192, 255, 64];
    const rgbCSSColor = `rgb(${color.join(',')})`;

または

    const aWidth = 10;
    const bWidth = 20;
    someElement.style.width = `${aWidth + bWidth}px`;

# JavaScriptのコーディング規則を学びましょう

自由にコードフォーマットする事ができますが、少なくとも1つの規則に注意する必要があります。 JavaScriptの変数名や関数名、メソッド名はすべてローワーキャメルケースです。 コンストラクターやクラスの名前はアッパーキャメルケースです。 このルールに従うなら、他のほとんどのJavaScriptコードと一致します。

多くの リンター] やコード内の明らかなエラーをチェックするプログラムは、間違ったケースを使用するとエラーを指摘します。 上記の規則に従うことで、エラーが間違っている事がわかるからです。

    const v = new vector(); // clearly an error if all classes start with a capital letter
    const v = Vector();     // clearly an error if all functions start with a lowercase latter.

# Visual Studio Codeの使用を検討する

もちろんあなたが望むエディタが良いですが、もし望むエディタがなければ Visual Studio Code を使う事を検討してみて下さい。 インストールし eslintをセットアップ します。 セットアップには数分かかる場合がありますが、バグを見つけるのに非常に役に立ちます。

いくつかの例

`no-undef` ルール を有効にすると、VSCodeのEsLintで多くの未定義の変数について警告します。

上記は `doTheThing` のスペルを `doThing` と間違えている事がわかります。 `doThing` の下に赤い波線があり、その上をホバリングすると定義されていない事がわかります。 1つのエラーが回避されました。 `THREE` を使用して警告が表示された場合、eslintに `THREE` が存在する事を伝えるため、JavaScriptファイルの先頭に `/* global THREE */` を追加します。

上記では、eslintは `アッパーキャメルケース` がコンストラクターであるというルールを知っているため、 `new` を使用する必要があります。 他のエラーをキャッチして避けます。これは`new-cap` ルール です。

数百のEslintルールをオン・オフにカスタム できます。 上記の例では `var` でなく `const` と `let` を使用するルールを適用しました。 コードでは `var` を使用しましたが、`let` または `const` を使用する必要があると警告されました。

ここでは `let` を使用しましたが、値を変更しない事がわかったため、 `const` を使用することが提案されました。

もちろん、 `var` を使い続けたい場合は、そのルールをオフにすることができます。 上記で記述したように `var` よりも `const` と `let` を使用することを好みます。 それらはうまく機能し、バグを防ぎます。

ルールをオーバーライドする必要がある場合、1行のコードまたはコードセクションに無効にするコメントを追加できます。

# レガシーブラウザをサポートする必要がある場合は、トランスパイラーを使用して下さい

ほとんどのモダンなブラウザは自動更新されるため、これらすべての機能を使用すると便利です。生産性を高め、バグを回避できます。 あなたのプロジェクトで古いブラウザをサポートする必要があれば、ES5/ES6/ES7コードをES5のJavascriptにトランスパイラーするツール を使用して下さい。