の前提条件

これらの記事は、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 '../../build/three.module.js';

...

</script>

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

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

document.querySelectordocument.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);

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

someobject.somefunction(a, b, c);

thissomeobject がセットされます。

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

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

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

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

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

ES5/ES6/ES7 stuff

var は非推奨です。 constlet を使って下さい

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);
}

forEachmapfilter は役に立ちます

配列の関数である forEachmapfilter はモダンな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を理解する

Getterssetters は ほとんどのモダンなプログラミン言語でよく使われます。 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";

上記の foobar は同様の意味になります.

もう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 でなく constlet を使用するルールを適用しました。 コードでは var を使用しましたが、let または const を使用する必要があると警告されました。

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

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

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

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

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