4歳娘「パパ、懐かしいJavaScript書いてるね!」


リモートワーク中ワイ

ワイ「お、社長からメールや!」
ワイ「また何か仕事をさせる気やな・・・!」

よめ太郎「(そらせやろ)」

ワイ「どれどれ・・・」

["たかし", 37, 173, 75]
↑この配列を元にオブジェクトを作ってくれ。

配列の中の4つの値は、それぞれ名前・年齢・身長・体重やで。

ワイ「ふーん」
ワイ「何やこの意味わからん仕事」
ワイ「まあええか、やってみよ」

やってみる

ワイ「まず、元の配列は・・・」

JavaScript
const array = ["たかし", 37, 173, 75];

ワイ「↑こうやな」
ワイ「ほんで、この配列の中の4つの値は」
ワイ「それぞれ名前・年齢・身長・体重を表しとるんやったな」
ワイ「ほな、分かりやすいように名前をつけたろか」

JavaScript
const array = ["たかし", 37, 173, 75];

const name = array[0];
const age = array[1];
const height = array[2];
const weight = array[3];

ワイ「↑こうやな」

娘(4歳)「パパ、懐かしいJavaScript書いてるね!

ワイ「・・・と言いますと?」

分割代入

娘「いまどきは、分割代入を使って↓こう書けばいいんじゃない?」

JavaScript
const array = ["たかし", 37, 173, 75];

const [name, age, height, weight] = array;

ワイ「ファッ!?
ワイ「これでname, age, height, weightっていう4つの変数を定義できるんか」

娘「そうだよ」
娘「ちなみに、nameageだけ使いたい場合は」

JavaScript
const [name, age] = array;

娘「↑こうも書けるよ」

ワイ「おお、後ろのほうの値は使わんこともできるんか」

娘「うん」
娘「逆に、後ろのほうの値だけを使うこともできるよ」

JavaScript
const [, , height, weight] = array;

娘「↑こうだね」

ワイ「おお」
ワイ「ありがとう、娘ちゃん・・・」

そこからオブジェクトを作る

ワイ「ほんで、オブジェクトを作らなあかんのやったな」
ワイ「ほな・・・」

JavaScript
const takashi = {
  name: name,
  age: age,
  height: height,
  weight: weight
};

ワイ「↑これでええか」

娘「もうちょっと楽に書けるよ」

JavaScript
const takashi = {
  name,
  age,
  height,
  weight
};

娘「↑これでいいんだよ」

ワイ「おお」
ワイ「変数名キー名と同じ場合は」
ワイ「そう書くだけでええんやね」

社長から次の指示

追加でお願いや。

["ひろゆき", 48, 175, 65]
↑この配列もオブジェクトにしてほしいんや。

ワイ「また似たような仕事やな」
ワイ「これはさっきの処理の使い回しでイケるな」
ワイ「ほな、さっきの処理を関数にして、使い回せるようにしておこか」
ワイ「配列を受け取って、オブジェクトを返す関数やから・・・」

JavaScript
const makePerson = (array) => {
  const [name, age, height, weight] = array;

  return {
    name,
    age,
    height,
    weight
  };
}

ワイ「↑こうやな!」
ワイ「人間っぽいオブジェクトを作るから、関数名はmakePersonや!」
ワイ「このmakePersonにさっきの配列を渡してやればええわけやから・・・」

JavaScript
const hiroyuki = makePerson(["ひろゆき", 48, 175, 65]);

ワイ「↑こうや!」

娘「さっそく分割代入を使ってるんだね」
娘「さすがパパ!」

ワイ「ゲヘヘ」

娘「でもね、分割代入は引数を受け取るときにも使えるから」

JavaScript
const makePerson = ([name, age, height, weight]) => {
  return {
    name,
    age,
    height,
    weight
  };
}

娘「↑こうでいいんだよ」

ワイ「おお、楽チンやな」
ワイ「ん?社長からまたメールや」

またまた追加指示

さっき作った人間オブジェクトを元に
「こんにちは!私はたかし!37歳だよ!」っていうテキストを生成する、
挨拶関数を作ってくれや。

ワイ「挨拶関数か。楽勝やな!」
ワイ「人間オブジェクトを受け取って、文字列を返す関数やから・・・」

JavaScript
const makeGreetingText = (person) => {
  const name = person.name;
  const age = person.age;
  return "こんにちは!私は" + name + "" + age + "歳だよ!";
};

ワイ「↑こうやな!」

娘「パパ、オブジェクトからも分割代入できるよ」

ワイ「と言いますと?」

娘「つまり・・・」

JavaScript
const makeGreetingText = ({name, age}) => {
  return "こんにちは!私は" + name + "" + age + "歳だよ!";
};

娘「↑これでいいってこと」

ワイ「Oh...素敵やん」
ワイ「ってことは例えば・・・」

JavaScript
const {name, age} = person;

ワイ「↑こういう書き方もできるんやね」

娘「そうそう」

ワイ「でも、person.nameperson.ageを」
ワイ「userNameとかuserAgeみたいな、ちょっと違う名前の変数に入れたい場合は・・・」

JavaScript
const userName = person.name;
const userAge = person.age;

ワイ「↑こう書くしかないんかな・・・?」

娘「ええとね」
娘「その場合は・・・」

JavaScript
const {name: userName, age: userAge} = person;

娘「こう書けばいいんだよ」

ワイ「おお、オブジェクトのプロパティ名と異なる名前の変数にもできるんや」

娘「うん」
娘「あとね・・・」
娘「文字列と変数を連結させてる部分も・・・」

テンプレート文字列

娘「↓こっちの方がいいかも」

JavaScript
return `こんにちは!私は${name}${age}歳だよ!`;

娘「テンプレート文字列ってやつだね」

ワイ「ほええ、文字列の中で変数の中身を展開してくれるんやね」
ワイ「なんや、PHPみたいやな」

またまたまた追加指示

ワイ「また社長からメールが来たで」

たかしには双子の弟がおるんや。
名前はいちろうや。
いちろうもオブジェクトにしてあげてや。

名前以外は、たかし全く同じや。

ワイ「たかしの弟がいちろうって、どないなっとんねん」
ワイ「たかし、無かったことにされとるやないか」
ワイ「まあええわ」
ワイ「たかしをコピーして作ればええやろ」
ワイ「配列をコピーするには、↓こうやな!」

JavaScript
const array = ["たかし", 37, 173, 75];
const copiedArray = [].concat(array);

ワイ「配列が持っとるconcatメソッドを使って」
ワイ「空配列に、コピー元の配列を連結してやると」
ワイ「配列をコピーできるんや」

娘「それでもいいけど・・・」

スプレッド構文

娘「↓こうも書けるよ」

JavaScript
const array = ["たかし", 37, 173, 75];
const copiedArray = [...array];

娘「...arrayスプレッド構文ってやつだね」
娘「配列を展開してくれるやつ」

ワイ「配列を展開・・・?」
ワイ「展開とは・・・?」

娘「ええと」

JavaScript
["たかし", 37, 173, 75]

娘「↑この配列を」

JavaScript
...["たかし", 37, 173, 75]

娘「↑こうスプレッド構文展開すると」

JavaScript
"たかし", 37, 173, 75

娘「↑こうしてくれる感じだね」
娘「両端にある[]を取ってくれる感じ」
娘「だから、展開

ワイ「なるほど、たしかに展開って感じやな」
ワイ「つまり」

JavaScript
const copiedArray = [...array];

ワイ「↑これはどうなるんや?」
ワイ「arrayには["たかし", 37, 173, 75]が入っとるわけやから」

JavaScript
const copiedArray = [...["たかし", 37, 173, 75]];

ワイ「↑こういうことやな?」
ワイ「ほんで、...が付いとるから」
ワイ「["たかし", 37, 173, 75]展開されて」
ワイ「"たかし", 37, 173, 75になって」

JavaScript
const copiedArray = ["たかし", 37, 173, 75];

ワイ「↑こういう意味になるってことか」
ワイ「だから配列がコピーされるんやな」

娘「そうそう」
娘「でも、一段階だけのシャローコピー(浅いコピー)だから注意してね?」
娘「配列の中に、更に配列が入ってたり、オブジェクトが入っている場合は」
娘「完全に複製されるわけではないから」

ワイ「せやったな」

娘「スプレッド構文は、複数の配列を連結させるときにも使えるよ」

JavaScript
const a = [1, 2, 3];
const b = [4, 5, 6];
const c = [7, 8, 9];

const abc = [...a, ...b, ...c];

娘「↑こうすると」

JavaScript
[1, 2, 3, 4, 5, 6, 7, 8, 9]

娘「↑こんな配列ができあがるの」

ワイ「おお、concatメソッドより直感的やな!」
ワイ「書きやすいし、読みやすい気がするわ!」

双子の弟「いちろう」を作る

ワイ「これで双子の弟『いちろう』を作ることができるな」

JavaScript
const array = ["たかし", 37, 173, 75];
const copiedArray = [...array];
copiedArray[0] = "いちろう";

ワイ「↑こんな感じで、名前だけ"いちろう"に変えてやって・・・」

JavaScript
const ichiro = makePerson(copiedArray);

ワイ「makePerson関数でオブジェクトにしてやればええんや」

娘「それでもいいけど、さっきtakashiっていうオブジェクトを作ったんだから」
娘「takashiをコピーしてnameだけ変えてもいいんじゃない?」

ワイ「そうか」

JavaScript
const ichiro = takashi;
ichiro.name = "いちろう";

ワイ「↑こうやな!」

娘「いや、それだとtakashiichiro同じオブジェクトを指していることになっちゃうから」
娘「takashiname"いちろう"になっちゃうよ」
娘「ていうか同一人物になっちゃうじゃん」

ワイ「まあ、双子なんやし、同一人物みたいなもんやろ・・・」

娘「いやいや全然違うでしょ
娘「タッチファンに◯されるよ?」

ワイ「なるほど、想像してみたら確かにマズイわ」
ワイ「ほな、ちゃんとオブジェクトを複製せなあかんのやな」

JavaScript
const ichiro = Object.assign({}, takashi);
ichiro.name = "いちろう";

ワイ「↑こうやな!」
ワイ「Object.assignメソッドで」
ワイ「空オブジェクトtakashiをマージしてやることで」
ワイ「takashiの複製を作ってやんねん」

娘「そんなときも、さっきの配列の時みたいに」
娘「スプレッド構文が使えるよ!」

JavaScript
const ichiro = {...takashi};
ichiro.name = "いちろう";

娘「↑こうだね」
娘「さらに・・・」

JavaScript
const ichiro = {
  ...takashi,
  name: "いちろう"
};

娘「↑こうも書けるよ!」

ワイ「ええ、何やその書き方」
ワイ「えらいスッキリ書けるんやな」
ワイ「ええと、スプレッド構文は両端のカッコを外してくれるイメージやったな・・・」

JavaScript
const ichiro = {
  ...takashi,
  name: "いちろう"
};

ワイ「↑このtakashiには・・・」
ワイ「{name: "たかし", age: 37, height: 173, weight: 75}が入ってるから・・・」

JavaScript
const ichiro = {
  ...{
    name: "たかし",
    age: 37,
    height: 173,
    weight: 75
  },
  name: "いちろう"
};

ワイ「↑こんなイメージか」
ワイ「ほんで、スプレッド構文が両端のカッコを外して展開してくれるから・・・」

JavaScript
const ichiro = {
  name: "たかし",
  age: 37,
  height: 173,
  weight: 75,
  name: "いちろう"
};

ワイ「こんなイメージやな」
ワイ「あれ、nameが2つになってしもうたで」

娘「その場合は、より後ろにあるname上書きされるよ」

ワイ「ほな結局・・・」

JavaScript
const ichiro = {
  ...takashi,
  name: "いちろう"
};

ワイ「↑この書き方をすると」

JavaScript
const ichiro = {
  name: "いちろう",
  age: 37,
  height: 173,
  weight: 75
};

ワイ「↑こういう感じになるわけか」
ワイ「オブジェクトをコピーしつつ、nameだけ上書き、みたいな」
ワイ「便利な時代になったもんやなぁ・・・」

娘「これもシャローコピーだから気をつけてね」

次は何をする

ワイ「ほんで結局、このtakashiichiroを使って」
ワイ「何をすればええんやろ」
ワイ「メールで社長に聞いてみよか」

ワイ「takashiichiro作りましたで」
ワイ「次は何をするんか教えてや」

ワイ「これでよし、と」
ワイ「おっ」
ワイ「さっそくお返事が来たで」

社長「いや何をするとかではないねん」
社長「ただちょっと・・・」
社長「・・・作ってみてほしかったんや」

ワイ「・・・」
ワイ「何やそれ!」
ワイ「酒飲む時間がなくなってもうたやんけ!」

よめ太郎「レガシー記法を脱却できたし」
よめ太郎「酒量も減るし、よかったやん」

〜おしまい〜

この記事もよろしくやで!

4歳娘「パパ、constしか使わないで?」

参考文献