演算子と型判定のあれこれ


##演算子 
* 演算子には様々な種類が存在する
* 演算時の**オペランド(被演算子)数**によって、**単項、２項、３項演算子**が存在する
* 3項演算子は、　**(条件式)?(結果１)：(結果２)**と書き、条件式がtrueなら結果１を、falseなら結果2を返すもの。オペランドが３つあるので３項演算子。



```js:js
//2項演算子
let value = 1;  //valueと１の2つのオペランドがあるので2項

//単項演算子
value++;  //演算子は++  オペランドはvalueのみなので単項
//2

//型判定の単項演算子
typeof value; //演算子typeof　オペランドはvalueのみなので単項
//number 

//3項演算子
value === 1 ? true : false; 
//false
```


##算術系演算子、型判定系


|    演算子名    |       記法        |                        意味                        | 項数 |
| :------------: | :---------------: | :------------------------------------------------: | :--: |
|   算術演算子   | + , - , * , / , % |           演算をする。単項と2項がある。            | 単,2 |
|   同値演算子   |      ==  ===      |      == は型判定せず比較、===は型判定込で比較      |  2   |
|   比較演算子   |  < , > , <= , >=  | 値の比較。異なる値の型同士では暗黙の型変換が起こる |  2   |
|   代入演算子   |         =         |                右辺を左辺に代入する                |  2   |
| 算術代入演算子 |     +=  , -=      |         算術演算子と代入演算子を並べて記述         |  2   |
| 論理演算子 | ! , &&  |  AかつB，AまたはBなど。遅延評価をすることに注意| 2|　　　　　　 

###演算子の注意点
* **単項演算子には前置演算子と後置演算子がある**
    * 前置は評価をするまえに演算
    * 後置は評価後に演算
* **等値演算と同値演算**
    * == は等値比較　値の型は問わない
    * === は同値比較　値の型を問う
* **比較演算子の暗黙の型変換**
    * *別のページ参照*
* **論理演算子の遅延評価ルール**
    * && は左オペランドが偽であれば、右オペランドは評価しない
    * || は左オペランドが真であれば右オペランドは評価しない
    * 遅延ルールに合致すれば、左オペランドを評価、そうでなければ右オペランドを評価

<br>
遅延ルールに関しては、考えればその通りな挙動をしている

* &&はどちらも合致する条件なので、一方でも偽であれば、あとは判定する必要がない
* ||はどちらかが合致すればよいので、一方でも真であれば、あとは判定する必要がない

なので、右オペランドの評価で終了する

#####以下に例を上げる
```js:js
//前置演算子　評価前に演算
let n = 10;
let m = ++n;
console.log(n, m);
//11 11

//後置演算子　評価後に演算
let n = 10;
let m = n++;
console.log(n, m);
//10 11


//等値比較と同値比較
const a = 1 == '1';  //true
const b = 1 === '1';  //false


//遅延評価
//左オペランドがfalse
let n = 0 && 1; //0

//左オペランドがtrue
let n = true && 1; //1

//左オペランドがtrue
let n = 1 || 2; //1

//左オペランドがfalse
let n = false || 'x'; // 'x'
//
```



##型判定演算子
|     演算子名     |          記法          |                    意味                    | 項数 |
| :--------------: | :--------------------: | :----------------------------------------: | :--: |
|     in演算子     |       key in obj       | オブジェクトのキーの存在判定。真偽値を返す |  2   |
|   typeof演算子   |      typeof value      |       値の型を判定する。真偽値を返す       |  単  |
| instanceof演算子 | obj instanceof class名 |  オブジェクトのクラスを判定。真偽値を返す  |  2   |


###型の種類
####値（データ型）の基本型6種とオブジェクト型

* 文字列
* 数値
* Boolean
* null
* undefined
* Symbol (ES6から)
* Object


####組み込み型オブジェクト（クラス）の種類
予め、JavaScriptに組み込まれているオブジェクトのこと
すべてのオブジェクトのベースとなる基本オブジェクトと、他のオブジェクトがある。
詳しくはこちら　[MDN 標準ビルトインオブジェクト](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects)


#####基本オブジェクト

* Object
* Function
* Boolean
* Symbol
* Error系


#####数、文字、配列、その他

* String
* Number
* Math
* Date
* RegExp
* Array
* JSON
* promise
* generator

ちなみに以下のものも予め組み込まれているもの

**グローバルプロパティ**

* infinity
* NaN
* undefined
* null

**グローバル関数**

* isFinite(testValue)
* isNaN()
* parseFloat()
* parseInt()
など


<br>

データ型やオブジェクトの判定のために、typeof演算やinstanceof演算を使う。またオブジェクトの判定には、Object.prototype.toStringを使うのもいい。

型についてはこちらの記事を参考にしました！
[JavaScriptの「型」の判定について](https://qiita.com/south37/items/c8d20a069fcbfe4fce85)


**データ型判定**

```js:js
typeof 'str';     // 'string'
typeof 1;         // 'number'
typeof true;      // 'boolean'
typeof null;      // 'object'
typeof undefined; // 'undefined'
```

**オブジェクトの判定**

Object.prototype.toStringはオブジェクトを表す文字列を返す。
call（）は、引数をで与えたものがtoStringメソッドをもつように扱うもの。
具体的にはこちら
[JavaScript の call( ) メソッドを雑に説明](https://qiita.com/Chrowa3/items/b3e2961c4930abc1369b)

```js:js
var toString = Object.prototype.toString

toString.call({});                // [object Object]  
toString.call([]);                // [object Array]
toString.call(function() {});    // [object Function]
toString.call(new Date());        // [object Date]
toString.call(JSON);              // [object JSON]
toString.call(Math);              // [object Math]
toString.call(new String('str')); // [object String]
toString.call(new Number(1));     // [object Number]
toString.call(new Boolean(true)); // [object Boolean]
```

しかしこの場合、自分で作成したクラスはすべてオブジェクトが返る
例は以下の通り

```js:js
function Dog(name) {
  this.name = name;
}

dog1 = new Dog('Gabby');
const a = dog1.toString(); //"[object Object]"　　(prototype継承しているので、prototypeは不要)
const b = Object.prototype.toString.call(new Dog()); //"[object Object]"　　（prototypeメソッドなので必要）
```

そのためinstanceof　演算子で判定する

```js:js
dog1 instanceof Dog; //true
dog1 instanceof Object //true
```




##オブジェクト生成等
|   演算子名   |    記法     |         意味          | 項数 |
| :----------: | :---------: | :-------------------: | :--: |
|  new演算子   | new Date(); |   オブジェクト生成    |  単  |
| delete演算子 |   delete    |   プロパティの削除    |  単  |
|  void演算子  |   void 0    | 必ずundefined値を返す |  単  |


##その他

|            演算子名            |         記法         |               意味               | 項数 |
| :----------------------------: | :------------------: | :------------------------------: | :--: |
|          カンマ演算子          |      x=2 , y=3       |    最後のオペランドの値を返す    |  2   |
| ドット演算子、ブラケット演算子 |  arr.length, arr[0]  | オブジェクトのプロパティアクセス |  2   |
|       関数呼び出し演算子       | fun();のカッコの部分 |          関数を呼び出す          |  2   |



カンマ演算子について


```js:js

console.log((x = 1, y = 2));
//2
//ｙ = 2の値が評価される
```