Javascript再勉強

長年C#erでしたが、そろそろJavaScriptを使いこなせるようになろうと思い再勉強しました。

# 変数

* 値には型があるが変数には型はない。

* 変数名には`$`も使える。

```js
var a$b = 1
```

* 特別な場合を除いて、宣言していない変数を使用しようとすると`ReferenceError`が発生する。

* 変数の宣言のみを行い、値の格納を行わなかった場合には、変数の値は`undefined`となる。

* 変数には格納されている値の型とは異なる型の値を再格納することができる。

```js
var a = 1
a = "a"
```

# 基本データ型

* 基本データ型は`Number`、`String`、`Boolean`、`Undefined`、`Null`の5つ。

# typeof

* 値の型を文字列として取得するには`typeof`演算子を使用する。C#の`typeof`とは異なる。得られる文字列は`"number"`、`"string"`、`"boolean"`、`"undefined"`、`"object"`、`"function"`の何れか。

```js
   typeof(1)
=> 'number'
   typeof("a")
=> 'string'
```

* 先述したように値には型があるが変数には型はない。`typeof`の対象として変数を指定した場合、変数が格納している値の型が取得される。ただし、宣言されていない変数を指定した場合であっても`ReferenceError`にはならず、`undefined`が得られる。

```js
   typeof(a)
=> 'undefined'
   var a = 1
   typeof(a)
=> 'number'
   a = "a"
=> 'a'
   typeof(a)
=> 'string'
```

# 数値

* 8進数は`0`から始める。16進数は`0x`から始める。

* 値の範囲は倍精度浮動小数点数の範囲。範囲外の値は`Infinity`又は`-Infinity`となる。

* 任意の数値を`0`で割っても`Infinity`が得られる（エラーにはならない）。

* `Infinity - Infinity`や`-Infinity + Infinity`の結果は`NaN`となる。

* 数値演算に失敗した場合も`NaN`が得られる（エラーにはならない）。

* `null`は`0`に変換される。

# 文字列

* 一重引用符で囲んでも文字列となる。
* 文字列のi文字目の文字を文字列として取得するには`"hello"[1]`のようにする。

# 真偽値

* 空文字列、`null`、`undefined`、`0`、`NaN`は`false`に変換される。それ以外の真偽値でない値は`true`に変換される。

# null

* `typeof(null)`は`"object"`となる。

# 比較

* `==`や`!=`は暗黙的に型の変換が行われる。たとえば、`1 == "1"`は`true`となる。暗黙的な型の変換が行われてほしくない場合には、代わりに`===`や`!==`を使用する。

* `NaN == NaN`は`false`となる。

# 配列

* 配列は`[1, 2, 3]`のように作成する。

* 配列には型がない。`[1, 2, "a"]`のように異なる型の値を含む配列を作ることができる。

* `a`が配列を格納している変数である場合、`a[6] = "b"`のようにして配列の要素を変更することができる。要素が存在しない場合には追加される。

* 配列の要素を削除する場合には`delete`演算子を使用する。

* 存在しない要素を参照した場合には`undefined`が得られる。

# 関数

```js
function sum(a, b) {
    var c = a + b;
    return c;
}
```

* 関数の引数に型はない。

* 関数名には`$`も使える。

* 明示的に値を返さない場合には、暗黙的に`undefined`が返る。

* 関数の呼び出しにおいて引数に値を渡さなかった場合には、その引数の値は`undefined`となる。余分に値を渡した場合には、その値は無視される。ただし、関数の中では`arguments`という変数が参照でき、この変数の値は引数として渡された全ての値から成る配列に似たオブジェクトである（余分に渡された値も併せて格納されている）。配列と同様に添字を使って要素を取得することができる。

* 関数の中で別の関数を定義することができる。

* 局所変数の有効範囲は関数単位である。

* 局所変数は関数の冒頭に**巻き上げられる**。したがって、下の関数はその下の関数と同じになる。

```js
function f() {
    alert(a);
    var a = 1;
    alert(a);
}
```

```js
function f() {
    var a;
    alert(a);
    a = 1;
    alert(a);
}
```

そのため、コード上、**局所変数宣言の前にその局所変数を使用してもエラーにはならない**。**同名の大域変数があっても、その大域変数はその関数から見えない**。

* 関数を変数に格納することができる。その場合、関数自体には名称を指定しなくても良い。

* 関数そのもの又は関数を格納した変数に対して`typeof`演算子を使用すると、`"function"`が得られる。

# オブジェクト

```js
var o = {
    prop1: yumina, 
    prop2: 25
}
```

* プロパティ名は引用符で囲んでも良い。ただし、プロパティ名が変数名として使用できないようなものである場合には、必ず引用符で囲まなければならない。

* `o["prop1"]`又は`o.prop1`のようにしてオブジェクトのプロパティの値を取得することができる。ただし、存在しないプロパティの場合には`undefined`が返る。

* `o["prop1"] = "b"`又は`o.prop1 = "b"`のようにしてオブジェクトのプロパティの値を変更することができる。存在しないプロパティの場合には指定した値でプロパティが追加される。

* オブジェクトのプロパティを削除する場合には`delete`演算子を使用する。

* 下のようにオブジェクトを作成するための関数を定義することもできる。ただし、その下のように`return`でオブジェクトを返した場合、`this`ではなくそのオブジェクトが返ることになる。しかし、その下のように`return`でオブジェクト以外のものを返した場合、`this`が返る。

```js
function O() {
    this.prop1 = "yumina";
    this.prop2 = 25;
}
```

```js
function O() {
    this.prop1 = "yumina";
    this.prop2 = 25;

    return {};
}
```

```js
function O() {
    this.prop1 = "yumina";
    this.prop2 = 25;

    return 1;
}
```

* [Javascriptで継承](http://qiita.com/pizyumi/items/15261272eaa4a1ad2f51)
* [Javascriptで継承（補足）](http://qiita.com/pizyumi/items/83a3a3a43c9d1a3ca2f0)

* オブジェクトのプロパティを列挙する場合には`for-in`を使用する。ただし、`for-in`でプロパティの列挙を行った場合にはプロトタイプから参照できるプロパティも含められる。