0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptのメカニズム(実行環境)

Posted at

参考

【JS】ガチで学びたい人のためのJavaScriptメカニズム

あらすじ

現場でrailsを触ってlaravelを触って今はtypescriptとreact-routerで実装することが多くなってきたが、今までJavascriptをがっつり勉強してなかったので復習も兼ねて上記講座を受けてみようと思った。

とある先輩から「エンジニアじゃない人間が聞いてもわかる程度の説明にしろ」という言葉をいただいたので、できるだけ頑張る。

ブラウザとJavaScriptの関係

ブラウザには以下の要素がある

  • UserInterfaceーuserに見える部分
  • DataStorageーデータを保存する場所
  • RenderingEnginーレンダリング(画面生成)の処理
  • JavaScriptEnginーJavaScriptが動く部分

JavaScriptEnginでJSが動く。ChromeはV8というエンジン。
エンジンの中でJavaScriptやWebAPIsが動く。V8はオープンソースなのでどの環境でも使える。これをUniversalJavaScriptという。
ちなみにfirefox等ブラウザごとに個体差があるので注意。

JavaScriptコードが実行されるまで

JavaScriptはJavaScriptエンジン内で処理が行われる。
具体的にはエンジンの中、実行前に3つ要素が準備されている。

  • 開発コード(自分で作ったコード)
  • グローバルオブジェクト(Windowオブジェクト、中にWebAPIsが含まれる)
  • this

thisに関して、thisはオブジェクトの参照を意味するもの。コンテキスト(コードの実行場所)によって取得できる値が変わる。初期値はWindowオブジェクト。

グローバルオブジェクトはJSエンジンによって生成されるコード内のどこからでもアクセスできるオブジェクト

大事なのはブラウザのグローバルオブジェクトはWindowオブジェクトとなること

実行コンテキストについて

プログラミングに関して、コンテキストとはコードを実行する際の文脈、状況である。
前述の開発コード、グローバルオブジェクト、thisをまとめたものが実行コンテキストと呼ばれる。
現在は主に以下のコンテキストがある

  • グローバルコンテキスト
  • 関数コンテキスト
    (moduleコンテキストもあるが今はこの2つを覚えておく。evalコンテキストはパス)

グローバルコンテキストの中身

  • 実行中(宣言した)のコンテキスト内の変数、関数
  • グローバルオブジェクト
  • this

以下のような状況がグローバルコンテキストを使用してると言える

const a = 0;
function b(){}

console.log(a);
b();

関数コンテキストの中身

  • 実行中(宣言した)のコンテキスト内の変数、関数
  • arguments
  • (super)
  • this
  • 外部変数

以下のような状況が関数コンテキスト内の宣言

const a = 0;
function b(){
    console.log(this, arguments, a)
}

b();

// 出力結果
// window //グローバルオブジェクト
// argumets //arguments
// 0 //外部変数

コールスタックについて

コールスタックとは、実行中のコードが辿ってきたコンテキストの積み重ね

function a(){
}

function b(){
    a();
}

function c(){
    b();
}

c();

chromeの開発者ツールでsourceにアクセスし、ブレイクポイントを決めてリロードすると動きが見られる。c()の時点で最初にCallStack内でanonymousが出るがこれはグローバルコンテキストの意味。進めていくとc->b->aとなり、aから消えていく。これを後入れ先だしという。

ホイスティング(hoisting)とは

コンテキスト内で宣言した変数や関数の定義をコード実行前にメモリーへ配置すること。

function a(){
    console.log('a is called');
}

a();

このコードは

a();

function a(){
    console.log('a is called');
}

でも動く。関数や変数は実行前にメモリへ保存されるため、コード上は後ろに書いても関数が存在している扱いになる。

各変数はどのような扱いになるか

varの場合

console.log(b);
var b = 0;

//出力結果
// undefined

実はこれでも動く。ただし出力結果はundefinedになる。
なぜこうなるかというと内部的にはこのような形になっている。

var = b
console.log(b);
b = 0

varという値をメモリに確保して、undefinedをセットしてるからundefinedが出る仕組み。そういうふうになっている。

let、constの場合

console.log(b);
let b = 0; //またはconst

//出力結果
// ReferenceError

letconstはundefinedによる初期値のセットが行われない

発展系

a();

function a(){
    d();
    function d(){
        console.log('d is called')
    }
}

// 出力結果
// d is called
// a is called

関数に関してはすでにメモリに確保されているので前に宣言していても呼べる

関数式

a();

const a = function a(){
    d();
    function d(){
        console.log('d is called')
    }
}

// 出力結果
// ReferenceError

const宣言で関数を定義できる。それを関数式という。この場合const扱いになるのでエラーになる。

基本は巻き上げ実装がよろしくないと思うので変数、関数はconstで実装しようって印象です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?