Javascript 为什么TypeScript为命名空间生成IIFE?
我有这个TS代码:Javascript 为什么TypeScript为命名空间生成IIFE?,javascript,typescript,namespaces,iife,Javascript,Typescript,Namespaces,Iife,我有这个TS代码: export namespace Constants { export var x = 0; } 如果我用“tsc”编译它,我会得到以下JS代码: "use strict"; exports.__esModule = true; exports.Constants = void 0; var Constants; (function (Constants) { Constants.x = 0; })(Constants
export namespace Constants
{
export var x = 0;
}
如果我用“tsc”编译它,我会得到以下JS代码:
"use strict";
exports.__esModule = true;
exports.Constants = void 0;
var Constants;
(function (Constants) {
Constants.x = 0;
})(Constants = exports.Constants || (exports.Constants = {}));
我的问题是。为什么“tsc”会将名称空间编译成IIFE,而不是像这样一个简单易读的对象
var Constants = {};
Constants.x = 0;
有什么特别的原因吗
这是有道理的。除了他们没有给出任何真实的答案。这个问题的不同之处在于,名称空间只是一个分隔代码的简单容器,那么它必须尽可能简单易读,而IIFE并不是实现这一点的最佳解决方案。名称空间就是一个范围。在JavaScript中提供作用域的经典方法是将代码放入函数中 特别是,IIFE是封装局部变量的一种方式:
export namespace Constants
{
const val = 2
export const x = val * 2;
}
// Here, 'val' must be inaccessible.
// And we can create another 'val' variable:
const val = 3; // OK
使用“简单对象”实现,楼上的代码将编译为:
const Constants = {};
const val = 2
Constants.x = val * 2;
// With this implementation, 'val' could be accessed outside the namespace at runtime.
// And we couldn't create another 'val' variable:
const val = 3; // Error: already defined.
我写了一篇评论,但也许一个答案是更好地表达我观点的恰当方式 我认为无法回答您的问题,因为这是TypeScript团队做出的选择 无论如何,我会把我对这个话题的想法写在这里 我认为他们不太关心生成的JavaScript代码的可读性 相反,他们只是关心它是否如预期的那样工作,而你的简单示例没有得到优化,我想这只是因为他们认为它不应该得到优化 命名空间与模块完全相同,可以包含代码、函数和类。它可以是巨大而复杂的 即使在简单的情况下,如您所示,普通对象的行为方式与函数相同,在JavaScript中es5在语义上也不相同 如果您在TypeScript中使用普通对象,那么它就是,但是名称空间是一个模块,JavaScrip es5上唯一的等价物是一个函数
我认为,如果您针对不同版本的JavaScript,例如具有模块的JavaScript,它可能会发生变化。很抱歉,但我认为您没有抓住重点。我同意你的观点,«这是一种封装局部变量的方法。»重点是:为什么一个生命而不是一个简单的对象?@AlterEgo我编辑了一个解释。对不起,古希腊,在回答之前仔细阅读这个问题。显然,您是对的«如果没有IIFE…“val”在运行时可以在名称空间之外访问»。但在本例中,您的实现不在当前竞赛中。@AlterEgo您需要澄清什么是“当前竞赛”。@AlterEgo-回复前是否阅读?第14页,1.10Namespaces@MarioSantini这个问题中给出的生成的ES5代码是完美的。没有一个字符需要更改。显然,TypeScript团队关心生成的代码。@我删除了我的评论,并回答了一个太长的问题。我希望它更有意义。