如何在JavaScript ECS6中声明命名空间

3

我习惯使用以下语法,我相信它被广泛使用:

var foo = foo || {};

(function() { 
    foo.bar = function(){
         return this;
    };
    foo.bar.prototype.stuff = null;      
    foo.bar.prototype.do = function(){...};
})();

这可以使用闭包实现,也可以不使用。

我使用foo.bar.prototype.stuff语法,以避免将所有定义放在构造函数中。

在ECS6中,我尝试了这种语法:

class Foo{};

class Bar{
    constructor(){
      this.stuff = null;
    }        
    get moreStuff(){ return this.stuff++;} 
    do(){...}
}

Foo.Bar = Bar;

module.exports = { Foo };

我发现在使用这种语法时,Intellisense在Visual Studio Code中非常方便。

有人看到这种语法有什么问题吗?如果有,请修改并提出更好的建议。

我阅读了这篇文章《如何在JavaScript中声明命名空间?》,发现许多提议的语法都是在ECS6之前提出的。


大多数情况下,我会说,为什么要将 Bar 分配到 Foo 上呢?你可以将它们都放在 exports 中,并从那里访问它们。 - loganfsmyth
@loganfsmyth 我有C#的背景,所以我习惯于在分层命名空间中构建我的代码,我相信在JavaScript中也很常见。如果有更好的方法,我会使用它。 - pasx
通常情况下,对于模块化的JS,文件本身就充当了命名空间,所以你只需要使用module.exports = Bar;即可。如果你需要这个类,可以使用文件路径来进行require() - loganfsmyth
1个回答

2
在ES2015+中,你不再需要这些虚假的命名空间了。相反,使用模块来代替。(也许需要一个模块加载器,因为对于模块的本地支持仍然只是在浏览器中逐渐推行。)
但是如果你想继续使用虚假的命名空间,或许暂时使用,直到原生的模块支持更加普及,那么你所拥有的就很好,尽管使用类声明class来声明 Foo 比将其作为对象放入原始示例中没有任何实际优势。
var Foo = Foo || {};
Foo.Bar = class Bar{
    constructor(){
      this.stuff = null;
    }        
    get moreStuff(){ return this.stuff++;} 
    do(){...}
};

除了给人一种可以使用Foo构建有用东西的印象之外,你的版本还不错,而且如果你在两个文件中这样做,它将失败(而你第一个示例使用var foo = foo || {};则允许您在两个文件中这样做,并在同一页上包含它们,可能一个定义foo.Something,另一个定义foo.SomethingElse)。


1
这个。我无话可说。 - Bergi
谢谢你的回答。你能详细说明如何使用模块来构建命名空间吗? - pasx
@pasx:你根本不需要在模块中使用这些伪命名空间。你只需从模块中export绑定,然后其他代码就可以import它们。没有任何全局变量,如果你不想的话,导入时也不必使用相同的名称(你可以导出Foo并导入Bob)。这消除了命名冲突(除了模块标识符)。任何一篇关于ES2015模块的好文章都应该能帮助你入门。 :-) - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接