Treasure2020 1日目
はじめに
こんにちは。トコロテンです。
ついこの間まで梅雨で脳みそ破壊されそうでした(偏頭痛)。 段々と暑くなってきて蝉の声も聞こえるようになると本当に「夏」が始まったんだなぁと実感します。
今年の夏は、VOYAGE GROUPさんのサマーインターンである「Treasure2020」と共に始まりました。 今回は、Treasure2020の初日に学んだことと感想をテキストに起こしたいと思います。
↑これかっこよくないですか。僕はかっこいいと思います。
JavaScript
みなさん、JavaScript書けますか?僕は書けません。
😎「でも、書けるようになるから大丈夫。そう、Treasureならね。」
初日は、フロントエンドの講義ということでJavaScriptの歴史やTipsを教えてもらいました。 挙動不審な言語として悪名高いJavaScriptですが、本講義を通して理解が深まりました。
講義の主な内容としては、以下のとおりです。
- プリミティブ型とオブジェクト型
- イベントループ(event loop)
- function式とアロー関数式
- Promiseオブジェクトとasync/await構文
プリミティブ型とオブジェクト型
プリミティブ型
プリミティブ型に属するデータ型は、以下の6種類です。
- 文字列
- 数値
- BigInt
- 真偽値
- undefined
- symbol
プリミティブ型は、以下のような特徴を持ちます。
- オブジェクトではない
- メソッドを持ない
- イミュータブル(変更不可)である
しかし、メソッドを持たないといった特徴がありながら以下のコードが動作します。
const hoge = "hoge"; console.log(hoge.toUpperCase());
hoge
は、文字列なのでプリミティブ型になりますが、toUpperCase()
メソッドを呼び出すことができます。
これは、各プリミティブ型に対応するラッパーオブジェクトといったものが存在し、自動的にオブジェクトに変換が行われているからだそうです(初めて知った)。
例えば、文字列の場合、以下のようにString
(string
ではないことに注意)に変換されて、メソッドの呼び出しが行われます。
const hoge = new String("hoge"); console.log(hoge.toUpperCase());
オブジェクト型
オブジェクト型は、任意のプロパティを持たせることができるデータ構造です。
分かりやすい例だと、以下のコードにあるobj
のようなものです。
const obj = { hoge: "hogehoge", fuga: "fugafuga", };
参照渡しと値渡し
プリミティブ型とオブジェクト型では、変数のコピーを行う際の挙動が異なります。 具体的には、以下のようになります。
- プリミティブ型: 値渡し
- オブジェクト型: 参照渡し
プリミティブ型(値渡し)
const hoge = "hoge"; let fuga = hoge; fuga = "fuga"; console.log(hoge === fuga); // => false console.log(hoge); // => "hoge" console.log(fuga); // => "fuga"
オブジェクト型(参照渡し)
const hoge = { data: "hoge" }; let fuga = hoge; fuga.data = "fuga"; console.log(hoge === fuga); // => true console.log(hoge.data); // => "fuga" console.log(fuga.data); // => "fuga"
上のコードから分かるように、オブジェクト型は、オブジェクトへの参照をコピーしているだけなので同一オブジェクトのプロパティを変更したりすることができます。 特に、関数にオブジェクト型の引数を渡すときには、内部でプロパティが変更されないかしっかりと考える必要があります。
イベントループ
JavaScriptは、DOMの更新や関数の実行等、様々なタスクを処理しますが、これらは全てシングルスレッドで行われているそうです。 つまり、並行処理はできても並列処理はできないということになります。 したがって、重い処理が走ると全体の処理をブロックしてしまいます。
例えば、以下のコードで実際にcounter
DOMの値が更新されるのは、times
の値が1000になってからです。
const button = document.getElementById('heavyCount'); const counter = document.getElementById('counter'); button.addEventListener('click', function() { let count = 0; let times = 1000; function loop() { if (count++ < times) { counter.innerHTML = count; loop(); } else { alert("Done"); } } loop(); });
このようになる理由は、loop()
関数が実行されるとシングルスレッドであるJavaScriptは、loop()
関数が終了するまでDOMの更新タスクを処理することができないためです。
これを回避するためには、以下のようにsetTimeout
等の関数を利用して非同期処理を行います。
タスクの一部が終わるごとにスレッドを明け渡し、次のタスクをキューに積むといったことをしてDOMの更新タスクが割り込めるようにします。
const button = document.getElementById('heavyCount'); const counter = document.getElementById('counter'); button.addEventListener('click', function() { let count = 0; let times = 1000; function loop() { if (count++ < times) { counter.innerHTML = count; setTimeout(loop); } else { alert("Done"); } } loop(); });
function式とアロー関数式
JavaScriptの関数の定義方法は、以下のようにfunction式を使う方法とアロー関数式を使う方法の2種類があります。
これら2つの方法は、若干異なる点が存在します。
その中でも、特に重要なthis
の束縛のタイミングの違いについて学びました。
- function式: 実行時にthisを束縛
- アロー関数式: 定義したときにthisを束縛
以下のコードを見ると関数の定義方法におけるthis
の束縛タイミングの違いが分かりやすいと思います。
function regular() { return this; } console.log(regular() === window); // true const arrow = () => { return this; } console.log(arrow() === window); // true const obj = { regular: regular, arrow: arrow } console.log(obj.regular() === obj); // true console.log(obj.arrow() === obj); // false
Promiseオブジェクトとasync/await構文
以下のように、Promiseオブジェクトとthen(), catch()を利用したコールバック処理からasync/await構文を利用してコールバックのネストを減らすことができます。 個人的な感想として、今あえてPromiseオブジェクトを使う理由というのは殆ど無いのではないかと思います。
const sleep = (msec) => { return new Promise((resolve, reject) => { setTimeout(() => resolve(msec), msec); }) } // Promise const f = (msec) => { sleep(msec).then((res) => { console.log("f: " + res); }); } f(1000); // async/await const g = async (msec) => { const res = await sleep(msec); console.log("g: " + res); } g(1000);
開発パート
講義の後半でSkyWayといったサービスを紹介してもらい、実際にSkyWayのSDKを利用してビデオチャットのWebアプリを開発しました。 はじめは、機能としてビデオ通話しか無いものでしたが、講義が終わった後も開発がとても楽しかったため、テキストチャットの機能や画像の送信機能を付けてみました。 開発するにあたって、React+TypeScript+SkyWay SDKを利用しました。
以下の画像が、作成したビデオチャットのスクリーンショットです。
さいごに
まだ1日しかインターンに参加していませんが本当に勉強になって幸せです。 プログラムに関しては、これまで殆ど独学だったため、人に教えてもらうということが新鮮でした。 今回の講義でレベルの高い方に教えてもらえるのはめちゃくちゃ効率的な勉強に繋がると実感しました。