28719


**下記のようなオブジェクトがありました**

* * *

**hogeオブジェクトはaプロパティを持つ**

> hoge  
>  ・a

* * *

**aオブジェクトは、bプロパティとhogeプロパティを持つ**

> hoge  
>  ・a  
>  ・b  
>  ・hoge

* * *

**コンソールで確認してみたら延々と続く**

> hoge  
>  ・a  
>  ・b  
>  ・hoge  
>  ・a  
>  ・b  
>  ・hoge

* * *

**質問**

・オブジェクトは、自分自身を、プロパティに含めても良いのでしょうか？  
・こうすることで、どういうメリットがある(と推察される)のでしょうか？  
・無駄なような気もするし、重複している(?)ので何となく遅くなるような気もするのですが…


CC BY-SA 3.0
2016-09-06T03:20:37.647
28713
2018-11-25T08:35:09.223
7886
question
javascript
オブジェクトは、自分自身(オブジェクト)を、自分のプロパティに含めても良い？ メリットは？


別に悪いことは無いです、というかJS実行環境が機能する時点でレファレンスがループしてるオブジェクトは絶対あるとおもいます（`Object.constructor`=>`Object()関数`、`Object()関数.prototype`=>`Object`など）。  
必要も無い（`this`でアクセスできる）のにプロパティとして保持している分メモリはほんの少し食うでしょうが、それによって処理が遅くなることは無いはずです（ものすごくメモリが足りない環境でプロパティ1つ分のせいでGCが実行してしまったりすれば別ですが）。  
利点も基本的には無いと思います。アルゴリズム上そうすると実装が楽になるとかはあるかもしれませんが。


CC BY-SA 3.0
2016-09-06T06:18:08.133
28716
2016-09-06T06:23:37.303
2016-09-06T06:23:37.303
3974
3974
28713
answer


許されます。  
APIやデータ構造の設計上、メリットというより自然にこうなる事があります。  
無駄という事はないです。無理にこの構造を避けるより効率的な筈です。ただ、この手のオブジェクトに対して、いわゆるディープコピーのように、全てのプロパティを再帰的に辿ろうとすると無限ループになりますから、そこは対策が必要です。

### 一般に起こり易い状況

データ構造の個々の要素をオブジェクトとし、その要素自身に何らかの参照を持たせるようにすると、特定の状況でその参照が自分自身になる事があります。

循環リストを考えてみます。  
個々の要素に次の要素を示す`.next`というプロパティを持たせるとします。  
[![3要素の循環リスト](https://i.stack.imgur.com/UNLAd.png)](https://i.stack.imgur.com/UNLAd.png)  
先頭も末尾もないつながったリスト構造が出来て、要素は`.next`でお互いを参照しています。  
ところが、要素が削除されていって残り一つになると「次の要素は自分自身」という状況になります。  
[![1要素の循環リスト](https://i.stack.imgur.com/VGfCC.png)](https://i.stack.imgur.com/VGfCC.png)  
ここで、`objA == objA.next // => true` となる訳です。

循環していない連結リストで考えると、例えば個々の要素に`.first`として「リストの最初の要素」への参照を持たせるとします。  
[![個々の要素が最初の要素を参照しているリスト](https://i.stack.imgur.com/Ee87U.png)](https://i.stack.imgur.com/Ee87U.png)  
リストの最初の要素の`.first`は自分自身ですから`objA == objA.first //=> true`となります。

* * *

ただ、JavaScriptではあまり連結リストを作ったりはしないですね。だから目にする事が少ないのかも知れません。  
それでも、ブラウザなどの実行環境でこういった構造を探す事は可能です。以下は思い付いた例です。

### オブジェクトが「プロパティのプロパティ」に自分自身を持つ例

質問の例と同じです(オブジェクトが「自分自身を、プロパティに含めて」いる例ではないですね)。

[code]

    var html_elm = document.documentElement;
    // 子の親は自分と等しいか
    html_elm.firstChild.parentElement == html_elm;
    // => true
    // DOM の世界では true
    
[/code]

### オブジェクトがプロパティに自分自身を持つ例

[code]

    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
    
[/code]


CC BY-SA 3.0
2016-09-06T07:11:19.410
28719
2016-09-06T07:11:19.410
3054
28713
answer


> ・オブジェクトは、自分自身を、プロパティに含めても良いのでしょうか？

自分自身と同じ型をプロパティに含むものは下記のようなものがあり、一般的に使用されています。  
(mjyさんの回答が詳しいです)

  * 単方向(双方向)リスト  
次(または前)の要素へのリンクを持つリスト

  * ツリー  
例えばDOMツリーのようにchildrenとして他の要素を持つような、ツリー構造をなすもの

> ・こうすることで、どういうメリットがある(と推察される)のでしょうか？  
>  ・無駄なような気もするし、重複している(?)ので何となく遅くなるような気もするのですが…

一般的に下記の特性を持ちます。

  * n番目の要素へのアクセスはO(n)  
1ずつ辿っていく必要があるため。最後の要素へのアクセスが遅い。

  * 先頭の要素へのアクセスが高速  
先頭要素の追加/削除が速い

  * 要素の追加/削除自体は高速  
前記の通り、n番目の要素へのアクセスは遅い。

要素を前から順番に処理していく場合などはデメリットを気にせず使用できますが  
一般的にJavaScriptではプロパティへのアクセス自体がそれほど速くありません。  
(forループで配列のlengthを変数に受けてから使用し、高速化を図る例のように)

扱うデータ構造に親子関係がない限りあまり使用しないかもしれません。

indexを使用したランダムアクセスが多い場合、Arrayを使用したほうがよいです。


CC BY-SA 3.0
2016-09-06T07:26:11.343
28720
2016-09-06T07:26:11.343
3068
28713
answer