名前空間したい
1const 名前空間 = {キー: 値};
GASエディターで直接.gs(.js)ファイルを編集していると、
プロジェクト内のすべての関数はファイルをまたいでグローバルに定義されます。
そのため、ファイル名を分けても、同じ名前の関数は共存できません。
もし、同じ名前の関数を使用する必要がある場合、 オブジェクト型を使って名前空間(のようなもの)を定義できます。 これは言語機能としての名前空間ではなく、 グローバルな関数名の衝突を避けるための、GASエディター上での実装上の工夫です。
注釈
オブジェクトを使った名前空間の作成は、モジュール(importやrequire)が標準化される以前のJavaScriptで一般的な方法だったようです。
GASエディターにはモジュールシステムがないため、今でも同じ発想が有効です。
1// ns1.gs
2const ns1 = {
3 sameFnName: function (arg) {
4 Logger.log("これは ns1 の関数");
5 }
6};
1// ns2.gs
2const ns2 = {
3 sameFnName: function (arg) {
4 Logger.log("これは ns2 の関数");
5 }
6};
1// ns3.gs
2const ns3 = {};
3ns3["sameFnName"] = function (arg) {
4 Logger.log("これは ns3 の関数");
5};
1// main.gs
2function main() {
3 ns1.sameFnName(); // -> これは ns1 の関数
4 ns2.sameFnName(); // -> これは ns2 の関数
5 ns3.sameFnName(); // -> これは ns3 の関数
6}
GASエディターでは、ns1.gs・ns2.gs・ns3.gs・main.gsのようにファイルを分けて保存しても、
1つのプロジェクトとしてすべてまとめて実行されます。
ns1・ns2・ns3はそれぞれ別の変数名なので、
中のsameFnNameという同じ名前のプロパティが衝突することはありません。
注意
ns3["sameFnName"]のようにブラケット記法でキーを指定する場合、
キー名はクォートで囲んだ文字列にする必要があります。
ns3[sameFnName](クォートなし)と書くと、
sameFnNameという名前の変数を探しにいってしまい、
そのような変数が存在しなければReferenceErrorになります。
注意
GASはV8エンジン対応でモダンなJSを使えるようになりましたが、ES6のモジュールシステムはサポートされてないらしいです。 いろいろがんばればモジュールシステムを使うこともできるようですが、ここでは深追いしません。
tsc + rollupが使える場合は
ここまでの「オブジェクトによる疑似的な名前空間」は、
GASエディターに直接コードを書くスタイル特有の工夫です。
tsc + rollup + claspのワークフローが組める場合は、
そもそもファイルごとにモジュールスコープが分かれるため、
この工夫自体が不要になります。
同じ関数名を別ファイルで使いたい場合は、
export/importで明示的にやり取りすればよく、
グローバルな名前の衝突を意識する必要はありません。
ヒント
TypeScriptにはnamespaceという専用の構文もあります。
@types/google-apps-scriptの型定義(GoogleAppsScript.Driveなど)は
実際にこの構文で書かれていますが、
これは型定義パッケージ側の実装の都合によるものです。
自分のプロジェクトのコードでモジュールを分けたい場合は、
namespaceではなくexport/importを使うほうが今風です。