JavaScriptでの名前空間に関するアイデア

　
久しぶりに娑婆の空気を吸った方がいいかなって。

# 名前空間ってそうじゃないだろ
最近、JavaScriptという言語で遊んでいるのですが、まあーめんどくさい。JavaScriptには名前空間という機能が存在しないので、入れ子オブジェクトにして変数管理したり、class使ったりしてせこせこする訳です。
　
例１：[【JavaScript入門】使わなきゃ損！名前空間をやさしく解説！](https://www.sejuku.net/blog/65850)
例２：[javascriptで名前空間を有効活用する方法](https://techblog.kayac.com/javascript-variable-scope.html)
例３：[お兄ちゃん！そこは名前空間パターンだよ！](https://yuzutan-hnk.hatenablog.com/entry/2019/01/27/182954)
```js
//グローバル変数を使う例
NAMEBOX = {}
NAMEBOX.a = "num = "//変数定義
NAMEBOX.func = (e) => {//関数定義
  return NAMEBOX.a + e * 10
}
console.log(NAMEBOX.func(1))//num = 10
```
```js
//即時関数を使う例
(() = => {
  let a = "num = "//変数定義
  let func = (e) => {//関数定義
    return NAMEBOX.a + e * 10
  }
  console.log(NAMEBOX.func(1))//num = 10
})()
```
まあーめんどくさい。一度でも他の言語で名前空間を使用したことがある人は分かると思いますが、上記のあれらは名前空間じゃないから…。どちらかといえばclassだから…。

## 名前空間のイメージ
僕はc++の名前空間ぐらいしかまともに知らないので、それベースでできると嬉しいです。いつでも名前空間を行き来できるかんじ。
```c++
#include <iostream>
#include <string>
//#include <windows.h>

//名前空間を作成
namespace NAMEBOX {
    std::string a = "num = ";//変数定義
    std::string func(int e) {//関数定義
        return a + std::to_string(e * 10);
    }
}

int main() {
    //main関数内で定義
    std::string str;

    //名前空間NAMEBOX内で実行
    using namespace NAMEBOX;
    str = func(1);//外で宣言されているstrは使える

    //名前空間std内で実行
    using namespace std;
    cout << str << endl;

    //system("pause");

    return 0;
}
```

## 実装
動くのは確認しましたが、デバッグは真面目にやってないのでよしなに。
```js
/*

namespace.js

*/

class namespace {
  constructor() {
    this.model_class = class {}
    this.space = {}
  }

  create_namespace(name = "", func = () => {return 0}) {
    this.space[name] = new this.model_class
    return this.using_namespace(name, func)
  }

  using_namespace(name = "", func = () => {return 0}) {
    if(name === "") {
      return func()
    }
    else {
      this.space[name].func = func
      return this.space[name].func()
    }
  }

  delete_namespace(name = "") {
    return delete this.space[name]
  }

  finish() {
    this.space = {}
  }
}
```
```js
/*

使用例

*/

function init() {
  //名前空間を操作するクラス
  let box = new namespace

  //名前空間を定義
  box.create_namespace("testspace", function() {
    this.a ="num = "//変数定義
    this.func1 = (e) => {//関数定義
        return this.a + e * 10
    }
  })

  //名前空間で実行したい内容を関数で渡す
  box.using_namespace("testspace", function() {
    console.log(this.func1(1))//num = 10
  })

  //名前空間に直接アクセスすることも可
  console.log(box.space["testspace"].func1(1))//num = 10

  //名前空間を削除(任意)
  box.delete_namespace("testspace")

  //削除後はアクセスできない
  console.log(box.space["testspace"])//undefined
}

init()
```

## 使いかた
namespace.jsの使いかたです。かなり簡単で、名前空間を操作するためのnamespaceクラスを作成して、その後はやりたいことに応じてメソッドを呼び出すだけです。
　
メソッドは以下参照。
```js
//新しい名前空間の作成
create_namespace(name, func)
//name : 名前空間の名前。
//func : 名前空間作成後にすぐに実行する関数。初期化用。(thisの参照が違うため、アロー演算子非推奨)

//名前空間でプログラムの実行
using_namespace(name, func)
//name : funcを実行する名前空間の名前。
//func : 実行する関数。(アロー演算子非推奨)

//名前空間の削除
delete_namespace(name)
//name : 削除したい名前空間の名前。
```

## むすび
~~おむすび美味しいよね。~~

上記の方法だと、namespaceクラスとそれをnewしたやつだけで名前空間を扱えるので、グローバル空間がベタベタ汚れません。なんて優しいんだ…………。

しかもクラス実装なので入れ子も簡単。名前空間のネストとかも簡単にできそうです。僕はめんどくさいのでよりませんが。

~~名前空間ぐらい公式でサポートしろよ！！~~

[twitter](https://twitter.com/metaphysicalba1)