类 和 TypeScript 中命名空间的区别
Difference between classes and namespaces in TypeScript
TypeScript 中的 classes
和 namespaces
到底有什么区别?我知道,如果你用静态方法创建一个 class,你可以在不实例化 class 的情况下访问它们,这正是我猜的命名空间的要点之一。
我也知道你可以创建多个同名的Namespace,它们的方法编译成JS后属于同一个函数
但我不知道什么时候使用一个或另一个...对我来说,最后,classes 和名称空间几乎相同,所以我想我遗漏了一些东西.. .
But I cant figure out when to use one or another...for me, at the end, classes and namespaces are almost the same, so I guess I am missing something...
当您想创建它的实例时使用 类,例如
class Foo {
x = 0
}
const foo = new Foo(); // instantiate
仅当您需要对类似 类/函数/变量等进行分组时才使用名称空间,例如
namespace Foo {
export class Bar {}
export class Bas {}
}
重叠
最终使用语法有重叠,例如类 上的静态可以 滥用 以表现得像命名空间。如果您遵循本指南,您可以忽略重叠部分。
你是对的。命名空间和静态 classes 是相似的。他们有一些共同的特点。它们都是 ES5 模式的语法糖,具有相似之处 - cf。 TypeScript playground:
给出的转译 JavaScript
// TypeScript
class C {
static readonly Name = 'C';
static print() {
console.log(`Name=${C.Name}`);
}
}
namespace N {
export const Name = 'N';
export function print() {
console.log(`Name=${Name}`);
}
}
// Usage
C.print();
N.print();
const c = new C();
const n = new N(); // TS Error: Cannot use 'new' with an expression whose type lacks a call or a construct signature
// Transpiled JavaScript
var C = /** @class */ (function () {
function C() {
}
C.print = function () {
console.log("Name=" + C.Name);
};
C.Name = 'C';
return C;
}());
var N;
(function (N) {
N.Name = 'N';
function print() {
console.log("Name=" + N.Name);
}
N.print = print;
})(N || (N = {}));
然而,他们也有自己的特点:
命名空间 仅存在于 TypeScript 中,不存在于 ECMAScript 中。它们可以被视为 IIFE 语法糖。它们可以嵌套(例如 A.B.C
)以类似于 C# 命名空间。由于 ECMAScript 6 (ES6/ES2015),在大多数情况下 ES6 模块比命名空间更有趣,因为它更容易处理文件级别的嵌套并保持代码结构平坦。
类 包括静态成员在 ES6 中也可用。它们也是“构造函数模式”的语法糖。静态 class 提供与命名空间相同的功能,但语法不那么常见 - 参见前面的示例。
所以从根本上说,每个模式都有自己与这些用例相关的理念:
- 对于静态(即+/- 全局)成员:大多数情况下是 ES6 模块; TypeScript 命名空间有时甚至在模块内部 - 参见 TS Doc;或者只是一个常量对象文字,
- 创建对象:classes (顺便说一句,也可以有静态成员,比如工厂方法),工厂函数,只是普通的对象文字,. ..
这些建议可以帮助生成更“惯用”的代码,即更易于阅读和维护。
但是您/您的团队拥有您的代码,决定权在您。您可以根据您的经验尝试不同的模式来比较它们。最后,如果这是你的选择,在命名空间上使用纯静态 classes 也不错,就像使用命名空间而不是 ES6 模块一样。
TypeScript 中的 classes
和 namespaces
到底有什么区别?我知道,如果你用静态方法创建一个 class,你可以在不实例化 class 的情况下访问它们,这正是我猜的命名空间的要点之一。
我也知道你可以创建多个同名的Namespace,它们的方法编译成JS后属于同一个函数
但我不知道什么时候使用一个或另一个...对我来说,最后,classes 和名称空间几乎相同,所以我想我遗漏了一些东西.. .
But I cant figure out when to use one or another...for me, at the end, classes and namespaces are almost the same, so I guess I am missing something...
当您想创建它的实例时使用 类,例如
class Foo {
x = 0
}
const foo = new Foo(); // instantiate
仅当您需要对类似 类/函数/变量等进行分组时才使用名称空间,例如
namespace Foo {
export class Bar {}
export class Bas {}
}
重叠
最终使用语法有重叠,例如类 上的静态可以 滥用 以表现得像命名空间。如果您遵循本指南,您可以忽略重叠部分。
你是对的。命名空间和静态 classes 是相似的。他们有一些共同的特点。它们都是 ES5 模式的语法糖,具有相似之处 - cf。 TypeScript playground:
给出的转译 JavaScript// TypeScript
class C {
static readonly Name = 'C';
static print() {
console.log(`Name=${C.Name}`);
}
}
namespace N {
export const Name = 'N';
export function print() {
console.log(`Name=${Name}`);
}
}
// Usage
C.print();
N.print();
const c = new C();
const n = new N(); // TS Error: Cannot use 'new' with an expression whose type lacks a call or a construct signature
// Transpiled JavaScript
var C = /** @class */ (function () {
function C() {
}
C.print = function () {
console.log("Name=" + C.Name);
};
C.Name = 'C';
return C;
}());
var N;
(function (N) {
N.Name = 'N';
function print() {
console.log("Name=" + N.Name);
}
N.print = print;
})(N || (N = {}));
然而,他们也有自己的特点:
命名空间 仅存在于 TypeScript 中,不存在于 ECMAScript 中。它们可以被视为 IIFE 语法糖。它们可以嵌套(例如
A.B.C
)以类似于 C# 命名空间。由于 ECMAScript 6 (ES6/ES2015),在大多数情况下 ES6 模块比命名空间更有趣,因为它更容易处理文件级别的嵌套并保持代码结构平坦。类 包括静态成员在 ES6 中也可用。它们也是“构造函数模式”的语法糖。静态 class 提供与命名空间相同的功能,但语法不那么常见 - 参见前面的示例。
所以从根本上说,每个模式都有自己与这些用例相关的理念:
- 对于静态(即+/- 全局)成员:大多数情况下是 ES6 模块; TypeScript 命名空间有时甚至在模块内部 - 参见 TS Doc;或者只是一个常量对象文字,
- 创建对象:classes (顺便说一句,也可以有静态成员,比如工厂方法),工厂函数,只是普通的对象文字,. ..
这些建议可以帮助生成更“惯用”的代码,即更易于阅读和维护。
但是您/您的团队拥有您的代码,决定权在您。您可以根据您的经验尝试不同的模式来比较它们。最后,如果这是你的选择,在命名空间上使用纯静态 classes 也不错,就像使用命名空间而不是 ES6 模块一样。