56492


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

* * *

## 【質問の主旨】

下記のコードのうち、`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]

* * *

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


CC BY-SA 4.0
2019-07-08T06:27:16.427
56488
2019-07-08T07:56:42.877
32232
question
javascript
parent[elems[i]] = parent[elems[i]] || {};の役割を教えてください

[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')`という別の名前空間を作るコードを呼んでもうまく動きます。


CC BY-SA 4.0
2019-07-08T07:20:28.143
56492
2019-07-08T07:20:28.143
3475
56488
answer


論理 OR 演算子では、それぞれのオペランドは **左から右** へ評価されていきます。

このとき、もし評価対象のオペランドを Boolean に変換したとき `true` であれば、 **そのオペランドの値**
を返します。また、もし評価対象のオペランドを Boolean に変換したとき `false` であった場合は、 **さらに右のオペランドを評価** します。

そして、最終的に一度も `true` と見なせる値が存在しなかった場合、以下のように **一番最後のオペランドの値** が返されます。

[code]

    console.log(false || undefined || 0); //=> 0
    console.log(undefined || 0 || false ); //=> false
    
[/code]

これを利用することで、特定の変数、プロパティの値が、 Boolean に変換したとき `false` になる値 (`undefined`, `null`,
0, 空文字列, `false`, `NaN`, `document.all`) であった場合に設定する **初期値** を返すことが出来ます。

[code]

    {
      let str;
      console.log(str); //=> undefined
      str = str || "初期値";
      console.log(str); //=> 初期値
    }
    
[/code]

* * *

ただし、もしも 特定の `false` と見なせる値を許可し、他の値を許可したくない場合は、それを行なうためのより具体的なコードを記述する必要があります。

例えば、空文字列は許可したいが、それ以外の `false` と見なせる値は許可したくない場合、以下のように記述することが出来ます。

[code]

    {
      let str = "";
    
      str = str || "初期値";
      console.log(str); // => 初期値
    
      str = "";
    
      if (!(str || str === "")) {
        str = "初期値";
      }
      console.log(str); //=> ""
    }
    
[/code]


CC BY-SA 4.0
2019-07-08T07:41:11.143
56493
2019-07-08T07:56:42.877
2019-07-08T07:56:42.877
32986
32986
56488
answer