[JavaScript]初心者が初見で必ずthinking顔になるもの特集

初心者が見た瞬間:thinking:になるもの特集です。
小テクだったり、省略記法だったり、、
実際私も出会って:thinking:になりました！

**追記**
[即時関数](https://qiita.com/kozzzz/items/b4cd57ead41fc6355afd#function)のところで説明にある
> 他には、+や-等でも動きます。

の"等"が気になった方に朗報です。こちらの記事で"等"を知ることができます！！ :tada::tada:
[[JavaScript] "!function() {}()"以外の即時関数を紹介するぜ](https://qiita.com/kozzzz/items/4a38d0954d0c871c200f)
よろしければ覗いてみてください！

## !!
### is 何
booleanへの型変換。
### 例
```js
const obj = { hoge: "hoge" }
function hasHoge() {
  return !!obj.hoge // => true
}
```
論理否定（！）を二つ繋げて、`boolean` への型変換をしています。
!の結果を!で評価しているんですね〜。

## JSON.parse(JSON.stringify(obj))
### is 何
ディープコピー。
### 例
```js
const deepCopy = JSON.parse(JSON.stringify(obj))
```
JavaScriptでディープコピーをする際は、現状ライブラリを使うか自分で実装するしかありません。
そんな時に楽にコピーする時の方法として使われます。
ただし、どんなオブジェクトも完全にコピーできるわけではないので注意が必要です。

## ??
### is 何
[Null合体演算子](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator)。
### 例
```js
const hoge = null ?? "default" // => "default"
const fuga = false ?? "default" // => false
```
`null` と `undefined` 以外なら左式の結果を返します。
便利なので使える環境ならぜひ使っていきましょう。

## obj?.hoge
### is 何
[オプショナルチェイニング演算子](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining)。
### 例
```js
obj = {
 fuga: "fuga"
}

obj?.hoge // => undefined
obj?.fuga // => "fuga"
obj?.fuga?.hoge // => undefined (繋げられるよ！)
```
参照する値がnullishだった場合、実行時エラーを発生させずに`undefined`を返してくれます。

今までオプショナルな値にアクセスする場合は、参照元が存在するかをチェックするのが主流でしたが、オプショナルチェイニング演算子で簡潔にかけるようになりました。

```js
// 下記は同じ意味
obj && obj.hoge
obj?.hoge
```

こちらも便利なので使える環境ならぜひ使っていきましょう。

## ~
### is 何
ビット否定演算子。
### 例
```js
if (~string.indexOf("hoge")) {}
```
ビット否定演算子を使用した条件判定をたまによく見かけます。

```js
console.log(~0) // => -1
console.log(~(-1)) // => 0
```
という結果になるので、判定結果に使われるようになったそうです。

## +"1"
### is 何
数値へ型変換。
### 例
```js
console.log(+"1") // => 1
console.log(+"a") // => NaN
```
変換できなかった場合`NaN`になるので注意です。

## -0
### is 何
マイナス0。
### 例
```js
0 * -1 // => -0
Object.is(+0, -0) // => false
+0 === -0  // => true
```
実は0には `+0`と`-0`が存在します。
思わぬ落とし穴となる可能性があることを心の片隅に置いておきましょう。
[JavaScript のデータ型とデータ構造 - JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Data_structures)

## !function(){}()
### is 何
即時関数。
### 例
```js
!function(){
  // 処理
}()
```
よく見かけるのはfunctionを括弧で括る方法ですが、`!`でも同じように動きます。
これは関数式として解釈されれば括弧である必要がないからです。
他には、`+`や`-`等でも動きます。

## obj || "default"
### is 何
デフォルト値の代入に使われるやつ。

### 例
```js
// res => {}
const hoge = res.hoge || "default" // => hogeに"default"が代入される
```
OR演算子はbooleanを返すものではありません。左辺がfalsyな値だった場合に右辺をそのまま返すものです。
上記例では、左辺が評価された結果`false`だったので右辺の値を代入する。という動きになります。
よくデフォルト値代入のテクニックとして使用されます。

## array.length = 0
### is 何
配列の削除。

### 例
```js
const array = ["a", "b", "c"]
array.length = 0 // => array = []
```
配列の中身を全消しするテクニックです。

## { propName }
### is 何
省略プロパティ名。

### 例
```js
const hoge = "ほげ"
const obj = { hoge } // => obj = { hoge: "ほげ" }
```
オブジェクト作成時の省略表記法です。
プロパティ名の指定のみでオブジェクトが作成されます。
例のようにプロパティ名と変数名が同じ場合に適応できます。
因みに関数版もあります。

```js
/*
const obj = {
  hoge: function(){}
}
*/
const obj = {
  hoge() {}
}
/*
注意：以下はアロー関数内のthisが指すものが変わってしまうので等価ではない
const obj = {
  hoge: () => {}
}
*/
```

## return;
### is 何
戻り値を省略したreturn。

### 例
```js
if (isHoge) {
  return;
}
```
return の戻り値を省略した場合、未定義(`undefind`)が返ります。
ガード節でのリターンだったり、何もしないを明示する際に使います。

## void 0
### is 何
undefinedの取得。

### 例
```js
if (hoge === void 0) {}
```
undefinedという変数を使用して取得することも可能ですが、undefinedは単なるグローバル変数なので書き換えられてしまいます。そこで`void 0`を使って安全に取得していたという経緯があるそうな。
因みに、たまによく見る`void(0)`も同じ意味です。

```html
<a href="javascript:void(0)"></a>
```
画面遷移を無効化するために `undefind` を指定しています。


## ...obj
### is 何
[スプレッド構文](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax)。

### 例
```js
// オブジェクトリテラル
const obj = {
  a: "a",
  b: "b"
}

const obj2 = {
  ...obj,
  c: "c"
} // => { a: "a", b: "b", c: "c" }

// 配列リテラル
const arr = ["a", "b"]
const arr2 = [...arr, "c"] // => ["a", "b", "c"]
```
新しいオブジェクトを作成する際によく使われます。
`obj.c = "c"`でいいじゃんと思う人もいるでしょう。
こちらはデータ構造をイミュータブルに保つことができるメリットがあります。


## {a, b} = obj
### is 何
[分割代入](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)。

### 例
```js
// オブジェクトの分割代入
const obj = {a: "a", b: "b"}
const {a, b} = obj // => a="a", b="b"

// 配列の分割代入
const arr = [1, 2]
const [a, b] = arr // => a=1, b=2
```
オブジェクトは対応するプロパティに個別に代入されます。
配列は対応する添字の要素が個別に代入されます。

## function hoge(a, b = 1) {}
### is 何
[デフォルト引数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Default_parameters)。

### 例
```js
function hoge(a, b = 10) {
  a // => undefined
  b // => 10
}
hoge()
``` 
引数が指定されていない場合に、デフォルト値を設定できます。
引数チェックの手間がなくなるのでこれまた便利ですね。

## function hoge(a, b, ...otherArgs) {}
### is 何
[残余引数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/rest_parameters)。

### 例
```js
function hoge(a, b, ...otherArgs) {
  a // => 1
  b // => 2
  otherArgs // => [3, 4, 5]
}

hoge(1, 2, 3, 4, 5)
```
残余引数で受け取った値は配列に格納されます。
引数の数が不定な場合にとりあえず受け取る時に使ったりします。


## 参考
[JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript)