俺のjs

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/%E4%BF%BA%E3%81%AEjs/)をご覧ください😀


## 連想配列の途中でkeyが存在しなくてもエラーにならないようにしたい

```js
// categoryまで存在しないと未定義エラーになる
if (data.items[item_id].category.name)
```

↓

```js
// Optional chaining を使う
if (data.items?.[item_id]?.category?.name)
```
または

```js
// 一個ずつチェックする
if (data.items &&
    data.items[item_id] &&
    data.items[item_id].category &&
    data.items[item_id].category.name)
```


## 配列のフィルタ（抽出）

```js
// row.idsの中にtargetIdsの値がひとつでも含まれているものを抽出する
const filterRows = rows.filter(function (row) {
    for(let targetId of targetIds) {
        if(row.ids.includes(targetId)) {
            return true;
        }
    }
    return false
});

// ↓↓↓

// someを使ってもっと簡単に書くこともできる
const filterRows = rows.filter(function (row) {
    return targetIds.some(/** string */ id => row.ids.includes(id))
});
```

[※あわせて読みたい](https://qiita.com/naoqoo2/items/213fb791527c270d609c#%E3%81%A7%E3%82%82%E5%88%A4%E5%AE%9A%E3%82%84%E4%B8%80%E9%83%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%8F%96%E5%BE%97%E3%81%97%E3%81%9F%E3%81%84%E3%81%A8%E3%81%8D%E3%81%AFsome%E3%81%A8%E3%81%8B%E4%BD%BF%E3%81%A3%E3%81%9F%E6%96%B9%E3%81%8C%E3%81%84%E3%81%84%E3%82%88)

## 配列やオブジェクトをループしたい

どちらもforEachで統一することにした！

```js

// 配列の場合
data = [
    'A',
    'B',
    'C'
];
data.forEach(function(value){
    console.log(value);
});

// オブジェクトの場合
data = {
    'a': 'A',
    'b': 'B',
    'c': 'C'
};

// keyだけ使いたいときはkeys
Object.keys(data).forEach(function(key){
    console.log(data[key]);
});

// valueだけ使いたいときはvalues
Object.values(data).forEach(function(value){
    console.log(value);
});

// 両方使いたい時はentries
Object.entries(data).forEach(function([key, value]){
    console.log(value);
});

```

### forEachに落ち着いた理由
- for of で配列やイテレーションを持つオブジェクト（[反復可能オブジェクト](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol)）を回すこともできるが、普通のオブジェクトは回せない。[※頑張ればできる。](https://ginpen.com/2018/12/15/for-of-statement/)
- for in でオブジェクト回せるが、[プロトタイプのやつも処理しちゃう](https://eslint.org/docs/rules/guard-for-in)からオススメしない。
- [ESLint の Airbnb スタイル](https://github.com/airbnb/javascript#iterators-and-generators)的にも使わないでいこうぜといった感じ。
- ただし<font color="red">forEach内でreturnしても意味ないので注意！！</font>→[参考](https://qiita.com/growsic/items/008d0bd9e93174132ffc)
    - forEach で continue したい
        - `return;` でできる
    - forEach で break したい
        - できないので some関数を使うか、このときは普通にfor inとかがいいかも...

### でも判定や一部データを取得したいときはsomeとか使った方がいいよ！

#### 例1

```js

/**
 * 配列の中に自分の名前が存在するか
 *
 * @param {string} id
 * @param {object} members
 * @returns {boolean}
 */
function isExistsMyName(myName, members) {
    let exists = false;
    Object.values(members).forEach(function (value) {
        console.log(value.name);
        if (value.name === myName) {
            exists = true;
        }
    });
    return exists;
}

// ↓ forEachではなくsomeがオススメ

function isExistsMyName(myName, members) {
    return Object.values(members).some(function (value) {
        return value.name === myName;
    });
}
```

### あとforEachの中でawaitしても意味ないよ！

```js
members.forEach(async (member) => {
    await getData(member);
});
```

とか書けちゃうけど実際はawaitしない。その場合はfor-ofとか使おう。
参考）https://qiita.com/frameair/items/e7645066075666a13063

### なのでforEachに統一できないね。。。臨機応変に行こう！


#### 例2

```js
/**
 * IDから名前を取得する
 *
 * @param {string} id
 * @param {object} members
 * @returns {string}
 */
function getName(id, members) {
    let name = '';
    Object.entries(members).forEach(function ([key, value]) {
        if (id === key) {
            name = value.name;
        }
    });
    return name;
}

// ↓ ループにこだわらなくたっていい

function getName(id, members) {
    return members[id] ? members[id].name : '';
}
```


## 関数の引数をまとめてみる

```js
const sampleFunction = (hoge, fuga, moga) => {}

↓

const sampleFunction = ({hoge, fuga, moga}) => {}

// メリットとしてObjectの引数であれば使う側も渡す側も順番を気にしなくても良くなる
```

## importとか

（時代が変わったので普通にブラウザで動くよ。）

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Test</title>
  <meta charset="UTF-8" />
  <script type="module">
    import hoge, { test as fooLoud } from './test.js';
    fooLoud();
  </script>
</head>
<body>
  <div id="App"></div>
</body>
</html>
```

```js:test.js
export const test = () => {
  alert('foo');
}
export default function test2() {
  alert('bar');
}
```

- defaultはどんな名前でもOK（ここではhoge）
- default以外は名前を一致させる必要がある 
    - `import { test } from './test.js';`
    - ただし`as` で名前変えれる

## 配列を空にしたい

```js
array.splice(0);
```

## 配列の要素を削除したい

https://qiita.com/naoqoo2/items/40aaf6f5ece2ccfaf948

## 画面遷移したい

```js
window.location.href = '/hogehoge';
```