質問: window」としており、変数にオブジェクトを代入している形となっているのですが、これは、「parent」という名前の「windowオブジェクト」というような捉え方で合っていますでしょうか? また、5行目では、「parent[names[i]]」となっており、parentが配列のような形で表されているのですが、windowオブジェクトは配列としても扱うことができるということでしょうか? 以上2点につきまして、ご解説いただけましたら幸いです。よろしくお願いします
回答: > > これは、「parent」という名前の「windowオブジェクト」というような捉え方で合っていますでしょうか? > > > はい、あってますよ オブジェクトを変数に代入するときは「参照の値渡し」です。 なんのこっちゃサッパリ分からないと思うので解説していきます。 ChromeブラウザはWebサイトを開いた時に、 JavaScript世界のwindowオブジェクトを自動で用意してくれます。 windowオブジェクトの実体はメモリ空間上に保存してあり、グローバル変数windowにはメモリ空間のアドレス値が入っています。 `var parent = window;`を行ったとき、 windowの「アドレス値」が宣言したparent変数にコピーされます。 ですのでparent.hogehogeという風にparentのプロパティを操作すると、windowオブジェクトのプロパティが釣られて変化します。 ``` var data1 = {name: "taro", score: 80}; var data2 = data1; data2.name = "jiro"; data2.score = 70; console.log(data1); // {name: "jiro", score: 70} console.log(data2); // {name: "jiro", score: 70} ``` > > windowオブジェクトは配列としても扱うことができるということでしょうか? > > > オブジェクトと配列は別物です。 単にオブジェクトのプロパティには2つのルールでアクセス出来るだけです。 オブジェクトの利用 - MDN ``` var data = {name: "taro", score: 80}; console.log(data.name); // taro console.log(data["score"]); // 80 ``` > > > ``` > parent[names[i]] = parent[names[i]] || {}; > parent = parent[names[i]]; > ``` > > for文の中身のこれですね。 for文の前に`var parent = window;`とかやってますが、parentってのは親という意味ですよね。 windowはwindowだから親でもなんでもないやん? `parent[names[i]]`はオブジェクトのプロパティへのアクセスルールの一つでしたね。 オブジェクトに紐づくプロパティは親子関係の様にも見えます。 * parent: オブジェクトそのもの * 子: オブジェクトのプロパティ という擬似的な親子関係を想像して、parent変数を用意しているのです。 for文の1行目は`parent[names[i]] || {}`を`parent[names[i]]`に代入しています。 JavaScriptでは、`A || B`を評価した場合、 まずAを単体でif文に放り込んでtrueになりそうなもの(1以上の数値や文字列、オブジェクトや配列などなど...)はAそのものが返って来ます。 もしAがfalseになりそうなものだったら、Bを返します。 ``` var data = {name: "taro", score: 80}; // data.nameは常に存在するので"taro"が返ってくる console.log(data.name); // taro console.log(data.name || "nanashi"); // taro // data.ageは用意していないので18になる console.log(data.age); // undefined console.log(data.age || 18); // 18 ``` or演算子`||`の右辺は`{}`ですね。 空のオブジェクトを作ってparentのプロパティに代入しています。 続いて変数の代入の続きです。 for文の二行目の`parent = parent[names[i]]`って何をやってるんでしょうか? えええ、`parent = window`してたよね?windowオブジェクトぶっ壊れるじゃんどうしてくれんの!?!? そうではありません。 オブジェクトを代入した変数に、別の値を代入した場合、オブジェクトのアドレス値参照が切り離されます。 百聞は一見に如かず、いつものdata変数でどうなるか試してみましょう。 ``` var data = {name: "taro", score: 80}; var data2 = data; data2.child = {name: "jiro", score: 0}; // data2はdataのアドレス値を捨てて、data.childのアドレス値に切り替わる data2 = data2.child; data2.score = 70; console.log(data); // {name: "taro", score: 80, child: {name: "jiro", score: 70}} console.log(data2); // {name: "jiro", score: 70} ```