Javascript TypeScript中类和名称空间之间的差异

Javascript TypeScript中类和名称空间之间的差异,javascript,class,typescript,namespaces,difference,Javascript,Class,Typescript,Namespaces,Difference,TypeScript中的类和名称空间之间到底有什么区别?我知道,如果您使用静态方法创建一个类,您可以访问它们,而无需实例化该类,这正是名称空间的要点之一 我还知道,您可以使用相同的名称创建多个名称空间,当编译到JS时,它们的方法将属于同一个函数 但我不知道什么时候应该使用它们……对我来说,最终,类和名称空间几乎是一样的,所以我想我遗漏了一些东西 但我不知道什么时候该用一个或另一个…对我来说,最后,类和名称空间几乎是一样的,所以我想我遗漏了一些东西 当您想要创建类的实例时,请使用类,例如 clas

TypeScript中的
名称空间
之间到底有什么区别?我知道,如果您使用静态方法创建一个类,您可以访问它们,而无需实例化该类,这正是名称空间的要点之一

我还知道,您可以使用相同的名称创建多个名称空间,当编译到JS时,它们的方法将属于同一个函数

但我不知道什么时候应该使用它们……对我来说,最终,类和名称空间几乎是一样的,所以我想我遗漏了一些东西

但我不知道什么时候该用一个或另一个…对我来说,最后,类和名称空间几乎是一样的,所以我想我遗漏了一些东西

当您想要创建类的实例时,请使用类,例如

class Foo {
 x = 0
}
const foo = new Foo(); // instantiate
仅当需要对类似的类/函数/变量等进行分组时才使用名称空间,例如

namespace Foo {
  export class Bar {}
  export class Bas {}
}
重叠
在最终使用语法中存在重叠,例如,类上的静态可以被滥用,使其行为类似于名称空间。如果遵循此指南,则可以忽略重叠

你说得对。名称空间和静态类是相似的。它们有一些共同的特点。它们都是ES5模式中的语法糖,具有相似性——参见:

//类型脚本
C类{
静态只读名称='C';
静态打印(){
log(`Name=${C.Name}`);
}
}
名称空间N{
导出常量名称='N';
导出函数print(){
log(`Name=${Name}`);
}
}
//用法
C.打印();
N.打印();
常数c=新的c();
常数n=新的n();//TS错误:无法将“new”与类型缺少调用或构造签名的表达式一起使用
//传输JavaScript
var C=/**@class*/(函数(){
函数C(){
}
C.print=函数(){
console.log(“Name=“+C.Name”);
};
C.名称='C';
返回C;
}());
var N;
(功能(N){
N.名称='N';
函数打印(){
console.log(“Name=“+N.Name”);
}
N.打印=打印;
})(N | |(N={}));
然而,它们也有自己的特点:

  • 名称空间仅在TypeScript中,而不在ECMAScript中。它们可以被看作是句法上的糖。它们可以嵌套(例如
    A.B.C
    )以类似于C名称空间。自ECMAScript 6(ES6/ES2015)以来,在大多数情况下,ES6模块比名称空间更有趣,因为在文件级别处理嵌套和保持代码结构平坦更简单

  • ES6中还提供了包含静态成员的类。它们也是“构造函数-函数模式”的语法糖。静态类提供了与名称空间相同的功能,但语法不太常见-请参见前面的示例

因此,基本上,每个模式都有自己与这些用例相关的哲学:

  • 对于静态(即+/-全局)成员:大多数情况下为ES6模块;TypeScript名称空间有时甚至在模块内部-请参阅;或者只是一个常量对象文字
  • 创建对象:类(也可以有静态成员,比如工厂方法)、工厂函数、普通对象文本
这些建议有助于生成更“惯用”的代码,即更易于阅读和维护


但是你/你的团队拥有你的代码,决定权在你。根据你的经验,你可以尝试不同的模式来比较它们。最后,如果您愿意,在名称空间上使用纯静态类也不错,就像使用名称空间而不是ES6模块一样。

如果您不打算实例化类,请不要使用它。@FelixKling我应该使用什么来代替它?那么静力学方法有什么意义呢?@jorge belano murphy:你能回顾我的答案并给我反馈(评论、标签有用、批准)吗?