JavaScriptがわけわからんぷーだったので真面目に勉強した

## はじめに
* 自己紹介　まともに理解せずにJavaScript使って糞コード量産する人間のクズ
* 参考書籍　「開眼！JavaScript」 サイ本読むと眠くなるので
* 以下の内容は本読みながらメモったり、コード書いてみたものです。
* 全然見当違いのこと書いてたらすいません。

## よく出る用語
* コンストラクタ関数：　オブジェクトを生成するための関数  
 - コンストラクタ関数を定義することで目的のオブジェクトを生成する。
* インスタンス：　コンストラクタ関数から返されたオブジェクト
* コンストラクタ：　インスタンスが持つプロパティ
* プリミティブ型：　これ以上単純化できないもっともレイヤーの低い値(プリミティブ値)を持つ 'string' 10 false とか
* prototypeプロパティ： インスタンス生成時に自動生成されるオブジェクト
* プロトタイプチェーン：インスタンスからコンストラクタ関数を参照して遡りprototypeプロパティを継承する。
 - プロパティ検索時にオブジェクト自身から見つからない場合プロトタイプチェーンを遡る。


```js
//コンストラクタ関数
var Const = function(hoge, hige){
  this.hoge = hoge;
  this.hige = hige;
}

//インスタンス作成
var inst = new Const('hogehoge','higehige');
console.log(inst) // Const {hoge:'hogehoge', hige:'higehige'};
```


## プリミティブ型
* Number(),String(),Boolen()はnew演算子を付けなければプリミティブ値の生成も可能
* プリミティブ型の変数は値を格納する
* オブジェクトと違いコピー元の変数の値を変更してもコピー先の値に影響を与えない
* 比較も値で行う

```js
var string = String('hoge');
var stringCopy = string;

console.log( string === stringCopy ); //true

string = String('hige');
console.log(string, stringCopy); // hige hoge
console.log( string === stringCopy ); //false
```

## オブジェクトの保存
* オブジェクトを持つ変数の値はメモリに保存される
* 変数はメモリのアドレスを保持している
* 変数の保持するアドレスを使用して値を参照する
* オブジェクトを持つ変数を別変数にコピーする場合値ではなくアドレスをコピーする
* アドレスを比較する
* 既存オブジェクトに値を代入する場合メモリ上の値が変更される

```js
var objectA = { hoge : 'hoge' };
var objectB = { hoge : 'hoge' };
var objectCopy = objectA;

console.log(objectA === objectB); // false
console.log(objectA === objectCopy); // true
console.log(objectB === objectCopy); // false

var objectCopy2 = objectCopy;
console.log(objectCopy2); // {hoge:'hoge'}

objectA.hoge = 'hige';
console.log(objectCopy2); // {hoge:'hige'}
```

## インスタンスのプロパティとメソッド
* constructor コンストラクタ
* delete演算子でプロパティを削除可能
* hasOwnProperty()でプロトタイプチェーン経由か確認可能
* in演算子でオブジェクトがプロパティを保持しているか確認可能。プロトタイプチェーンの継承も見る

## prototypeプロパティとプロトタイプチェーン
* prototypeプロパティから継承することでメソッドなどの再利用が可能
* インスタンスのプロパティ__proto__にリンクされる
* 遡って最初に見つけた値を返す
* Object.prototypeまで遡ってプロパティが見つからない場合はundefinedを返す
* インスタンスは常に最新の値を取得
* ただしプロパティを新しいオブジェクトに変えた場合はインスタンスは更新されない

```js
var ProtChain = function(hoge){
  if(hoge){ this.hoge = hoge; }
}
ProtChain.prototype.hoge = 'hogehoge';
ProtChain.prototype.hige = 'hige';
ProtChain.prototype.returnStatus = function(){
  return this.hoge + this.hige;
}

var chain = new ProtChain('hoge');
console.log(chain.returnStatus()); //hogehige;

//引数hogeないためprototypeプロパティのhogehogeが返される
var chain2 = new ProtChain();
console.log(chain2.returnStatus()); //hogehogehige;

//最新の値を取得する
ProtChain.prototype.hige = 'higehige';
console.log(chain.returnStatus()) // hogehigehige;


//prototypeプロパティにインスタンスを継承
var ProtChainExtend = function(fuga){
  this.fuga = fuga;
}
ProtChainExtend.prototype = chain;

chainExtend = new ProtChainExtend('fuga');
console.log(chainExtend.hoge); // hoge
console.log(chainExtend.fuga); // fuga
console.log(chainExtend.returnStatus()); //hogehigehige;

//prototypeプロパティをオブジェクトに置き換え
ProtChain.prototype = {
  hoge : 'hogeReplace',
  hige : 'higeReplace',
  returnStatus : function(){
    return this.hoge + this.hige;
  }
};

//過去のインスタンスは更新されない
console.log(chain.returnStatus()); // hogehigehige

//新しいインスタンスを作成
var chain = new ProtChain();
console.log(chain.returnStatus()); // hogeReplacehageReplace
```

## this
* thisの参照先は使う場所により異なる
* 関数内のthisは格納するオブジェクトを参照
* 入れ子関数内のthisはグローバルオブジェクトを参照
 - 親関数にthisの参照を保持して回避可能
* call()とapply()で関数内のthisを設定可能
* コンストラクタ関数内のthisは生成されるインスタンスを参照
* prototypeに追加された関数内のthisはメソッドを呼んだインスタンスを参照


## まとめ
* とりあえずよくわかっていなかった部分をある程度理解できた（つもり）