質問: **下記のようなオブジェクトがありました** --- **hogeオブジェクトはaプロパティを持つ** > > hoge > > ・a > > > --- **aオブジェクトは、bプロパティとhogeプロパティを持つ** > > hoge > > ・a > > ・b > > ・hoge > > > --- **コンソールで確認してみたら延々と続く** > > hoge > > ・a > > ・b > > ・hoge > > ・a > > ・b > > ・hoge > > > --- **質問** ・オブジェクトは、自分自身を、プロパティに含めても良いのでしょうか? ・こうすることで、どういうメリットがある(と推察される)のでしょうか? ・無駄なような気もするし、重複している(?)ので何となく遅くなるような気もするのですが...
回答: 許されます。 APIやデータ構造の設計上、メリットというより自然にこうなる事があります。 無駄という事はないです。無理にこの構造を避けるより効率的な筈です。ただ、この手のオブジェクトに対して、いわゆるディープコピーのように、全てのプロパティを再帰的に辿ろうとすると無限ループになりますから、そこは対策が必要です。 ### 一般に起こり易い状況 データ構造の個々の要素をオブジェクトとし、その要素自身に何らかの参照を持たせるようにすると、特定の状況でその参照が自分自身になる事があります。 循環リストを考えてみます。 個々の要素に次の要素を示す`.next`というプロパティを持たせるとします。 !3要素の循環リスト 先頭も末尾もないつながったリスト構造が出来て、要素は`.next`でお互いを参照しています。 ところが、要素が削除されていって残り一つになると「次の要素は自分自身」という状況になります。 !1要素の循環リスト ここで、`objA == objA.next // => true` となる訳です。 循環していない連結リストで考えると、例えば個々の要素に`.first`として「リストの最初の要素」への参照を持たせるとします。 !個々の要素が最初の要素を参照しているリスト リストの最初の要素の`.first`は自分自身ですから`objA == objA.first //=> true`となります。 ただ、JavaScriptではあまり連結リストを作ったりはしないですね。だから目にする事が少ないのかも知れません。 それでも、ブラウザなどの実行環境でこういった構造を探す事は可能です。以下は思い付いた例です。 ### オブジェクトが「プロパティのプロパティ」に自分自身を持つ例 質問の例と同じです(オブジェクトが「自分自身を、プロパティに含めて」いる例ではないですね)。 ``` var html_elm = document.documentElement; // 子の親は自分と等しいか html_elm.firstChild.parentElement == html_elm; // => true // DOM の世界では true ``` ### オブジェクトがプロパティに自分自身を持つ例 ``` window == window.window; // => true // Webクライアントにおいて、window はグローバルな名前空間であり、 // 自分もグローバル変数に入っているので自分自身を持つ事になる(しかも同名で) var obj_to_str = Object.toString; // 自分を文字列化するのは自分自身か obj_to_str == obj_to_str.toString; // => true // 自分もオブジェクトなので true // このケースは継承を通じた自己の参照 obj_to_str.hasOwnProperty("toString"); // => false obj_to_str == Object.getPrototypeOf(obj_to_str).toString; // => true ```