JavaScript再入門 #1
2020/09/16
JavaScriptの歴史について
1990年代に下記のブラウザで利用されたプログラミング言語がルーツ。
- Netscape NavigatorがJavaScript
- Internet ExplorerがJScript
この2つが互換性がなかったためECMAScriptとして仕様策定した事でブラウザ間での仕様を統一した。
ECMAScriptはあくまで仕様であり、 JavaScriptの一部の仕様がECMAScriptである。
ブラウザの場合、JSの機能の中に下記の2点が存在する。
- ECMAScript
- WEB APIs、DOMAPI etc…
NodeJSの場合、JSの機能の中に下記の2点が存在する。
- ECMAScript
- CommonJS
JavaSctriptとは、ECMAScriptの仕様に基づいて実装されているプログラミング言語であり、実行する環境によって利用できる機能が変わってくる。
ECMAのバージョンについて
これまでの種類としては、
- 2009年 / 5版 / ES5
- 2015 / 6版 / ES2015(ES6)
- 2016 / 7版 / ES2016(ES7)
- 2017 / 8版 / ES2017(ES8)
- 2018 / 9版 / ES2018(ES9)
- ES6からは1年ごとにリリースされている。
- なぜなら仕様策定の仕組みが変わったため。
仕組みの名前は「Living Standard」
機能ごとに仕様を策定して仕様が決まったものから最新版の仕様書に追加していくスタイルへと変わった。
- 仕様策定プロセス
- Stage0 - アイデアレベル
- Stage1 - 機能提案・検討
- Stage2 - 暫定的に仕様決定
- Stage3 - テスト・実装
- Stage4 - 仕様決定
Stage2まで通過したものは基本的に次のバージョンに追加される。
- ECMAのサイトは「こちら」
- 新しい機能を実装しようか迷う場合は上記を確認してStage2まで行ってれば実用性があるな…などの判断ができる。
JavaScriptエンジンとは何か
ブラウザには下記のような、さまざまな機能が搭載されている
- ユーザーインターフェイス
- レンダリングエンジン
- ネットワーキング
- ブラウザーエンジン
- データストレージ
- JavaSctript エンジン
- UI バックエンド
上記の中でJavaScriptが実行される環境のことをJavaSctript エンジンといい、JSエンジンの中で下記が動いている。
- ECMAScript
- Web APIs
ちなみにChromeで動いているJSエンジンはV8と呼ばれるもの。
- V8エンジン自体はOSSのため、さまざま環境に組み込んでJSを実行する環境を作成する事が可能。
- こういった様々なソフトウェアで動く事が可能なJSをUniversal JavaScriptという。
各Browserが搭載したJSエンジンは下記の通りで、ほとんどのBrowserでV8が利用されている。
- Chrome : V8
- Safari : JavaScriptCore
- Firefox : SpiderMonkey
- Edge : Chakra / V8
- Opera / V8
基本的にJSからWebAPIsを操作することで、やりたい事を実現していくこととなる。
コードが実行されるまで
JavaScriptエンジン内では、事前に下記のものを用意している。
- グローバルオブジェクト
- ブラウザではwindowオブジェクトとなる
- this
windowオブジェクト
windowオブジェクトの中にはWebAPIsが事前に用意されており利用する事ができる。
- alert, document など
this
オブジェクトへの参照を保持しているがコンテキストによって参照先が変わる。
- グローバルコンテキスト
- 関数コンテキスト
- evalコンテキスト
- eval自体が非推奨になったため基本的に利用しない
グローバルコンテキスト
下記のものが実行できる
- 実行中のコンテキスト内の変数・関数ができる
- グローバルオブジェクト
- this
関数コンテキスト
下記のものが実行できる
- 実行中のコンテキスト内の変数・関数が利用できる
- arguments
- super(特殊な状況でのみ利用できる)
- this
- 外部変更
コールスタックとは
実行中のコードがたどってきたコンテキストの積み重ねであり、JSエンジンがどのような処理をたどって実行されたのか記録したもの
- devtool内のSourceからjsファイル自体を選び、ブレイクポイントを指定する事で詳細を確認する事が可能。
function a() {
}
function b() {
a();
}
function c() {
c();
}
c();
// コールスタック(下記の順番で消滅していく)
// a
// b
// c
// グローバル
このようなスタックの仕組みを、後入れ先出し LIFO(Last In Fast Out)という。
ホイスティングとは
コンテキスト内で宣言した変数や関数の定義をコード実行前にメモリーに配置すること(宣言の巻き上げ)
- functionやvarはコンテキストに応じて、メモリ上に定義を予約する
a(); // 'hoge'
function a(){
console.log('hoge');
}
// var b; を宣言しているのと同じ扱いになる
console.log(b); // undefined.
var b = 0;
console.log(b); // 0
- constやlet、関数式の場合は巻き上げされない。
c(); // Error
const c = function(){ // 関数式
console.log('hoge');
}
console.log(d); // Error
let d = 0;
console.log(d); // 0