parent[elems[i]] = parent[elems[i]] || {};の役割を教えてください


いつもお世話になっています。  
下記の質問についてご存知の方がいらっしゃいましたらご教示を願います。

* * *

## 【質問の主旨】

下記のコードのうち、`parent[elems[i]] = parent[elems[i]] || {};`
はどのような役割をするために存在するのでしょうか？

[code]

    var namespace = function (ns) {
        // 名前空間を「.」で分割
        var elems = ns.split('.');
        var parent = window;
    
        // 以降の名前空間を順に階層付けしながら登録
        for (var i = 0; i < elems.length; i++) {
            // parent[elems[i]] = (parent[elems[i]]) ? parent[elems[i]] : {};
            parent[elems[i]] = parent[elems[i]] || {};
            parent = parent[elems[i]];
        }
        console.log(parent);
        return parent;
    }
    
    // MyApp.Recipe.Sample名前空間を登録
    var ns = namespace('MyApp.Recipe.Samples');
    
    // 名前空間配下にクラスを定義
    ns.MyClass = function () {};
    var c = new ns.MyClass();
    console.log(c instanceof MyApp.Recipe.Samples.MyClass);
    
[/code]

## 【質問の補足】

### 1.

上記のコードは「JavaScript逆引きレシピ
第2版」のP269より引用したコードで、大規模アプリを作ることを想定して、名前を階層状に管理するためのコードです。

<https://www.shoeisha.co.jp/book/detail/9784798157573>

### 2.

`parent[elems[i]] = parent[elems[i]] || {};` と `parent[elems[i]] =
(parent[elems[i]]) ? parent[elems[i]] : {};` は同義であることは理解できます。

### 3.

コードを実行してコンソール画面を確認すると、以下の結果が表示されます。

[code]

    {}
    MyClass: ƒ ()
    __proto__: Object
    true
    
[/code]

* * *

以上、ご確認よろしくお願い申し上げます。



[code]

    if (!parent[elems[i]]) {
        parent[elems[i]] = {};
    }
    
[/code]

と書いた方が理解しやすいと個人的に思います。

このコードはサンプルコードの中では以下のような動きをします:

  * `window.MyApp` が存在しなかったら空のオブジェクトを `window.MyApp` に代入する
  * `window.MyApp.Recipe` が存在しなかったら、空のオブジェクトを `window.MyApp.Recipe` に代入する
  * `window.MyApp.Recipe.Samples` が存在しなかったら、空のオブジェクトを `window.MyApp.Recipe.Samples` に代入する

空のオブジェクトを繋いでいくことで、サンプルの最後にあるような`MyApp.Recipe.Samples`というドット区切りの名前空間を表現します。

いちいち存在チェックをすることで、あとで`namespace('MyApp.Recipe.Examples')`という別の名前空間を作るコードを呼んでもうまく動きます。



[code]

    if (!parent[elems[i]]) {
        parent[elems[i]] = {};
    }
    
[/code]

と書いた方が理解しやすいと個人的に思います。

このコードはサンプルコードの中では以下のような動きをします:

  * `window.MyApp` が存在しなかったら空のオブジェクトを `window.MyApp` に代入する
  * `window.MyApp.Recipe` が存在しなかったら、空のオブジェクトを `window.MyApp.Recipe` に代入する
  * `window.MyApp.Recipe.Samples` が存在しなかったら、空のオブジェクトを `window.MyApp.Recipe.Samples` に代入する

空のオブジェクトを繋いでいくことで、サンプルの最後にあるような`MyApp.Recipe.Samples`というドット区切りの名前空間を表現します。

いちいち存在チェックをすることで、あとで`namespace('MyApp.Recipe.Examples')`という別の名前空間を作るコードを呼んでもうまく動きます。

