[WIP] MDN web docs JavaScriptの要点メモ書き

# 名称

- JavaScript® は、米国およびその他の国における、Oracle の商標または登録商標。
- JSとも略される。

# 歴史

- Mozilla の Brendan Eich によって考案された。

# 規格

- ECMA International が ECMA-262 および ECMA-402 として規格化。ECMA-262 がJS本体。1992年制定。ECMA-402 はi18n対応。2012年制定。
- 2015年に制定された規格は、公式にはECMA2015、非公式にはES6と略される。

# 特長

- 第一級関数
- 動的なスクリプト型
- プロトタイプベース
    - mixinが可能
    - 実行時に型解決
- マルチパラダイム
    - オブジェクト指向
    - 命令型
    - 関数型
- マルチプラットフォーム
    - サーバサイド（Node.js等）
    - クライアントサイド（ECMAScript）

# 字句

## リテラル

### NULLリテラル

null。

### 真偽値リテラル

Boolean型と真偽値リテラルは別物。`new Boolean(false)`は`true`になる。そして、BooleanオブジェクトとBoolean関数も別物。まとめるとこんな感じになる。

```javascript
// Booleanオブジェクト
new Boolean(true) // true
new Boolean(false) // true
// Boolean関数
Boolean(true) // true
Boolean(false) // false
// 真偽値リテラル
true //true
false // false
```

要するにBooleanオブジェクトを使うとfalseがtrueになってしまうらしい。

以下サイト参照。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Boolean


### 数値リテラル

- Decimal
    - 10進数。0始まりで以降が8未満の数字のみだと8進数扱いされる。
- Binary
    - `0b`または`0B`はじまりの2進数。
- Octal
    - `0o`または`0O`はじまりの8進数。
- Hexiadecimal
    - `0x`または`0X`はじまりの16進数。
- 浮動小数点リテラル

### オブジェクトリテラル

リテラルを文の先頭で使わないようにしてください。{ がブロックの始まりと解釈されるため、エラーや予期せぬ動作を引き起こすことになります。」とのこと。怖すぎる。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Grammar_and_types#Object_literals

### 配列リテラル

### 文字列リテラル

### 正規表現リテラル

スラッシュで囲まれた文字列。

```javascript
/xxx/
```

### テンプレートリテラル

- ES6から登場
- バックスラッシュで囲まれた文字列。

```javascript
`Hello ${user} !`
```

## プリミティブ型

以下7つ。

### Boolean

`true` と `false`のみ。

### Null

`null` のみ。

### undefined

`undefined` のみ。

### Number：数値

以下の3種類。

- 数値リテラル
    - 正数、負数
        - `+, -`と0から9までの数字で表現される。
        - 値はすべてIEEE 754として扱われる。つまり、64ビット倍精度浮動小数点数。
    - 0
        - `+0`と`-0`がある。
- 数値オブジェクト
    - `+Infinity`、 `-Infinity` と `NaN` がある。

### String

Cとは異なり、変更不能な文字列。

- 文字列リテラル
- テンプレートリテラル

### Symbol

### Object

## セミコロン

- セミコロンはなくてもいいが、ないとブラウザが自動で挿入することがECMAで定義されている。詳細は以下参照。
    - https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Lexical_grammar#%E8%87%AA%E5%8B%95%E3%82%BB%E3%83%9F%E3%82%B3%E3%83%AD%E3%83%B3%E6%8C%BF%E5%85%A5
    - https://news.codecademy.com/your-guide-to-semicolons-in-javascript/

## 識別子

- 関数、変数、定数等々の名前をまとめて識別子という。
- 識別子は以下の命名規則に従う。
    - はじめは文字、`_`または`$`。
    - Unicode文字おｋ。
    - 大文字小文字は区別。

# スコープ

## 基本

- 関数の外側でブロックの外側
    - 全ファイルからアクセス可能なグローバル。
    - 自動的にグローバルオブジェクトwindowのプロパティになっている。
- 関数の外側でブロックの内側
    - ES6以前はブロックスコープがなくグローバルになっていた。
    - ES6からは`let`を使うとブロックスコープになる。
- 関数の内側
    - 関数内に閉じたローカルスコープ

## 巻き上げ

- 変数
    - ES6以前では関数の巻き上げという現象があり、以下の文は例外を起こすことなく、undefinedを返していた。
    - ES6からは`ReferenceError`を返す。
- 関数
    - 関数宣言は巻き上げられる
    - 関数式は巻き上げられない（関数式は第1級関数では変数と同じ扱いになるだろうから、当然といえば当然。）

```javascript
console.log(kannkyo + 1); // undefined
var kannkyo = 123;
```

# 関数

## 引数

### デフォルト引数

```javascript
function add(a, b=1) { return a + b; }
add(2) //3
```

### 残余引数

```javascript
function add(...a) {
  var result = 0;
  a.map(x => result += x)
  return result;
}
add(1, 2, 3, 4) //10
```


## 関数定義

### 関数宣言

```javascript
function add(a, b) { return a + b; }
add(1, 2) //3
```

### 関数式

```javascript
var add = function (a, b) { return a + b; }
(1, 2) //3
```

### アロー関数

```javascript
var add = (a, b) => a + b;
add(1,2)
```

### クロージャ

クロージャはデザインパターンの１つ。[カリー化](https://qiita.com/KDKTN/items/6a27c0e8efa66b1f7799)に用いられる。

```javascript
function method(n){
  var number = n;

  function closure(power){
    return number ** power;
  }

  return closure;
}
var result = method(2)(10); // 1024 = 2 ** 10
```

### 即時実行関数式

即時実行関数式は、IIFE (Immediately Invoked Function Expression)とも呼ばれるデザインパターンの１つ。

```javascript
(function (){
  console.log('do IIFE');
})();
console.log('finish');
```

void演算子を用いて以下のようにも書くことができる。

```javascript
void function (){
  console.log('do IIFE');
}();
console.log('finish');
```

# 予約語(ECMA公式、命令)

## const

- 配列の中身とオブジェクトのプロパティは定数化できない。

## continue

Javaとおなじ。

## debugger


## delete


## while, do...while

Javaとおなじ。

## for, for...in, for...of

- for
    - Javaとおなじ。
- for...in
    - オブジェクトのプロパティ名でループできる。
- for...of
    - オブジェクトのプロパティ値でループできる。

```javascript
var object = [10, 20, 30];
object.p = 'aiueo';

for (var i=0; i<=object.length; i++) {
  console.log(object[i]);// 10 20 30 undefined
}

for (var property_name in object) {
  console.log(property_name);// 0 1 2 p
}

for (var property_value of object) {
  console.log(property_value);// 10 20 30
}
```

## function


## if...else

Javaとおなじ。

## instanceof


## new


## return


## switch...case...break...default

Javaとおなじ。

## this


## throw


## try...catch...finally

Javaとおなじ。

## typeof


## var


## void


## with

# 予約語（ECMA公式、リテラル）

## null 


## true


## false

# 予約語（将来実装、strictでの利用不可）

## class


## enum


## export


## extends


## import


## super

# 予約語（将来実装、strictでの利用可）

## implements

## interface

## let

## package

## private

## protected

## public

## static

## yield

# 演算子

## 代入演算子

単なる代入とは別に以下の代入演算子と代入方法がある。

- 複合代入演算子(`+=`等)
    - ほぼJava等と同じだが、符号なし右シフト代入`>>>>=`が特殊。
- 分割代入
    - ほぼPythonと同じ。 `var [first, ,end] = ['最初', '真ん中','最後'];`的な代入ができる。

## 比較演算子

概ねJavaと同じだが、以下だけ独特。

- 等価 `==`
    - 自動的に型を変換した上で比較する。
    - `0 == '0'`や`0 == false`は真となるが、`1 == true`は偽となる。ややこしい。
    - オブジェクトの比較は全く同じメモリを指す場合だけ真となる。要はポインタ比較。
- 不等価 `!=`
    - 等価の逆。
- 厳密等価 `===`
    - 等しくかつ型が一致する場合に真。それ以外で偽となる。
- 厳密不等価 `!==`
    - 厳密等価の逆。

## 算術演算子

概ねJavaと同じだが、以下だけ独特。

- 単項プラス `+`
    - 数値でないものに単項プラスをつけると数値にされる。
    - `+null`は0になり、`+undefined`は`NaN`になり、`+true`は1となる。ややこしい。

## ビット演算子

概ねC言語と同じだが、すべての被演算子は演算前に32ビット整数に変換されてしまうことに注意が必要。

### ビット論理演算子

ビット論理演算子には以下の4つがあり、C言語とほぼ同じ。
- 論理積
- 論理和
- 排他的論理和
- 否定

### ビットシフト演算子

- 左シフト `a << b`
    - c言語の左シフト相当。
- 符号維持右シフト `a >> b`
    - 右シフトした上でMSBの値はシフト前と同じにする。1なら1。
- ゼロ埋め右シフト `a >>> b`
    - c言語の右シフト相当。

## 論理演算子

以下のようにC言語とほぼ同じだが、文字列はtrue扱いされるので要注意。またC言語と同様に短絡評価される。

- 論理和
    - `a && b`のうち`a`がfalseなら`a`を、それ以外では`b`を返す。
- 論理積
    - `a || b`のうち`a`がtrueなら`a`を、それ以外では`b`を返す。
- 否定

## 文字列演算子

## 条件（三項）演算子

## カンマ演算子

「JIS X 3010 プログラミング言語C」のコンマ演算子相当。

## 単項演算子

- delete
    - varで定義したものはdeleteできない。
- typeof
    - Javaとかと同じ。
- void
    - Javaとは異なり、型名ではなく演算子名。何を突っ込んでもundefinedが返ってくる演算子。

## 関係演算子

- in
- instanceof
    - JavaScriptはプロトタイプベースの言語であり、Javaのインスタンスは存在しない。インスタンスかどうかというより、同じprototypeを持っているかどうかをチェックするだけである。

# 式

## 基本式

- this
- グループ化演算子`( )`

## 左辺式

Javaとほぼ同じ。

- new
- super
- 展開演算子 `...`


# そのた

## undefined

## NaN

## Infinity

## null

# ブラウザについて

- タブはそれぞれ独立した実行環境になっており相互に情報のやり取りはできない。（普通は）