aoma blog

エンジニアの日常とか技術とか

昨今のJavaScriptをレビューしたら全くわからなかった話

この記事は移転したため新記事へ移動します。
移動しない場合はココをクリックして新サイトをお楽しみください。

はじめに

最近JavaScriptのプルリクが来たので「よーしやったるでー」って感じでレビューしたんですが、まったく理解できずレビューになりませんでした。

その時疑問に思ったことをメモします。。
誰かの助けになれば幸いです。。

これはもう引退やな。。

classの中で function って書くの省略してるの?

class TestClass {
    test() {
        処理
    }
}

function を省略して書けるのかなと思ったらそうではない。むしろ書いてはいけない。 下記はエラーになる。

class TestClass {
    function test() {
        処理
    }
}

PHPに慣れてるからか、もやもやする。

(a, b) => は無名関数なのはわかったけど function(a, b) じゃダメなの?

(a, b) => は無名関数で function(a, b) と同じ。

好みの問題だがthisに違いがある。

this.hoge;
function(a, b) {
   this.hoge; ←違うもの
}
this.hoge;
(a, b) => {
   this.hoge; ←同じ!こっちのほうがthisが何を指してるかわかりやすい!(外と同じthisになってる)
}

... ってなんや...

... はスプレッド演算子
中身バラす(展開する)やつ。
こんな感じで使う。

var parts = ['shoulders', 'knees']; 
var lyrics = ['head', ...parts, 'and', 'toes']; 
// ["head", "shoulders", "knees", "and", "toes"]

Arrayだったりオブジェクトだったりいろいろあるらしい。。詳しくはこちら

こんな感じで引数としても使える。無限引数。

const testFunction = (...items) => {
    items.forEach(function(item) {
        console.log(item);
    });
}

testFunction('aaa');
testFunction('aaa', 'bbb', 'ccc');

{} は処理書き忘れ?

{} は空のオブジェクト宣言。 function の処理の中身ないやつかと思ったらオブジェクトだった。なるほど、、まぁたしかに。。

reduce 関数とかで出てくる。

var countedNames = names.reduce(function (allNames, name) { 
  if (name in allNames) {
    allNames[name]++;
  }
  else {
    allNames[name] = 1;
  }
  return allNames;
}, {});

copy2clipboard = copy; って何してるんや...

copyクリップボードにコピーする関数。 https://blog.leko.jp/post/copy-function-of-developer-tools/

小技として、 promiseの中とかで使おうとすると名前解決できなかったりするので、

copy2clipboard = copy;

のように、事前にクローンしておいて、

this.copy2clipboard("logloglog");

みたいな感じで使える。

Mapって何や...

new Map(kvArray);

Mapは配列を連想配列にするクラス。Mapは型。
{} とは別。{} はキーに数値を使えないじゃん、ちゃんとした連想配列作ろうよ!ってことでMapができた。

詳しくはこちら

await 恐怖症や...

awaitはasyncが指定されてるときに使える。処理が終わるまで待つ。

awaitがないとthis.usersValidnesにプロミスが入って、this.usersValidnes自体にthenがないのでプロミスのまま生き続ける。処理は終わるけど結果が取れない。

hensu;
hoge().then(e => {
   hensu = e;
})

hensu;
hensu = await hoge()

は一緒。

awaitをなくすと

hensu= hoge()

となり、thenがないことになるので、

hensu.then(e=>~~~~)

してあげる必要がある。

hoge()は5秒くらいで"A"という文字列を返すプロミスだとする。

hensu = hoge();
await hensu; // 処理が終わるまで待つ
console.log(hensu) // 終わったプロミスが表示されるだけ

下記ならば値が取れる

hensu = hoge();
hensu2 = await hensu; 5秒かかる
console.log(hensu2) // "A"
hensu = hoge();
await hensu; // 処理が終わるまで待つ
console.log(await hensu) // ”A”
console.log(await hensu) // ”A”
console.log(await hensu) // ”A”
console.log(await hensu) // ”A”

とかはできる。 awaitは「プロミスを結果に変換する関数」だと考えるとわかりやすい!

async*アスタリスクは何なんや!

* はジェネレータになる。ふつうはfuctionにつく。classだとfunction書けないのでasyncに付いたりする。

yield (いーるど)って何やねん!

ジェネレータ用のキーワードreturn みたいなもの。

yieldreturn する。次呼ばれると yield の下から処理が始まる。

では yield* は一体何なのか...

yield を返すときは yield* としなければいけない。 return ではダメらしい。

function* func1() {
  yield 42;
}

function* func2() {
  yield* func1();
}

ややこしい。。詳しくはこちら

const って上書きできるの?

for await (const record of recordsGenerator) {
    処理
}

constを上書きしてるように見えるが、そうではない。

constは上書きできないので下記は当然エラーになる。

const a = 1;
const a = 2;

が、ここでは下記のような事になるので、スコープが違うのでエラーにならない。

{
   const a=1;
}
{
   const a=1;
}
// constを上書きしているのではなく別モノを定義している。

さいごに

近年のJSはぼくの知ってるJSちゃんじゃなかった。。大人になってた。。