TypeScript 中的枚举:JavaScript 代码在做什么

Enums in TypeScript: what is the JavaScript code doing?

本文关键字:代码 什么 JavaScript 枚举 TypeScript      更新时间:2023-12-14

以下 TypeScript:

enum PrimaryColors { Red, Green, Blue };

生成以下 JavaScript:

var PrimaryColors;
(function (PrimaryColors) {
    PrimaryColors[PrimaryColors["Red"] = 0] = "Red";
    PrimaryColors[PrimaryColors["Green"] = 1] = "Green";
    PrimaryColors[PrimaryColors["Blue"] = 2] = "Blue";
})(PrimaryColors || (PrimaryColors = {}));
;

我很尴尬地承认我不明白JavaScript在做什么。
括号中的函数使用另一个赋值作为索引/键来分配字符串值。我以前从未见过这样的事情。
以及(原色||(原色 = {}( 跟随函数?
如果答案是正确学习 JavaScript,我会欣然接受它,只要它附带一个建议的来源,清楚地解释我在这里看到的内容。

我相信:

PrimaryColors[PrimaryColors["Red"] = 0] = "Red";

相当于:

PrimaryColors[0] = "Red";
PrimaryColors["Red"] = 0;

请参阅此参考。

表达式 x = 7 是第一种类型的一个示例。此表达式 使用 = 运算符将值 7 赋给变量 X。这 表达式本身的计算结果为 7。

例如:

console.log((x = 7));

输出:

7

同样地:

var x = {};
console.log((x["hi"] = 7));

还输出 7。

<小时 />

至于第二件事,PrimaryColors最初是不确定的。

var x;
console.log(x); // undefined

在布尔上下文中,undefined计算结果为false

console.log(!undefined); // true
console.log(!!undefined); // false

健全性检查:

console.log((!undefined) === true); // true
console.log((!!undefined) === false); // true
console.log(undefined === false); // false

这是短路的常见用法。由于PrimaryColors最初是未定义的 (false(,因此它将{}传递给函数。

PrimaryColors || (PrimaryColors = {})

也许这会有所帮助。

(function() {})();

这是一个"立即执行的功能"。它将函数定义为表达式,然后调用它。

var x = y || y = {};

如果是将某些内容初始化为默认值的常见模式。如果 y 没有值,则 or 语句的第一部分为 false,因此它会执行第 2 部分,该部分为 y 赋值。第二个表达式的值是 y 的新值。所以 x 变成了 y 的值——如果它还没有定义,那就是新值。

x[y] = z;

JS中的对象是关联数组。换句话说,字符串对象对,如 IDictionary(string,object(。此表达式在字典 x 中将值为 y 的键设置为 z 的值;

x[x["a"] = 0] = "a";

所以,这里同样的事情,但有一个嵌套的表达式,即:

x["a"] = 0;

因此,这只是设置键"a"的值。没什么好看的。但这也是一个表达式,其值为 0。因此,将其替换为原始表达式:

x[0] = "a";

键必须是字符串,所以它实际上与:

x["0"] = "a";

它只是在字典中设置了另一个键。结果是这些陈述是正确的:

x["0"] === "a";
x["a"] === 0;

我发现了这个问题,因为我想知道当您可以立即使用 {} 初始化 var 时,为什么要使用 IIFE。前面的答案没有涵盖它,但我在 TypeScript Deep Dive 中找到了答案。

问题是,枚举可以拆分为多个文件。你只需要显式初始化第二个、第三个等枚举的第一个成员,这样:

enum Colors {
    Red,
    Green,
    Blue
}
enum Colors {
    Cyan = 3,
    Magenta,
    Lime
}

转译为:

var Colors;
(function (Colors) {
    Colors[Colors["Red"] = 0] = "Red";
    Colors[Colors["Green"] = 1] = "Green";
    Colors[Colors["Blue"] = 2] = "Blue";
})(Colors || (Colors = {}));
var Colors;
(function (Colors) {
    Colors[Colors["Cyan"] = 3] = "Cyan";
    Colors[Colors["Magenta"] = 4] = "Magenta";
    Colors[Colors["Lime"] = 5] = "Lime";
})(Colors || (Colors = {}));

您可能知道,在同一范围内重新声明变量是无害的,但重新初始化则不是。

我想他们可能会去:

var Colors;
Colors || (Colors = {});
Colors[Colors["Cyan"] = 3] = "Cyan";
// ...

并跳过关闭,但也许我仍然缺少一些东西。

它用于创建一个关联的映射(换句话说,一个对象(,您将通过使用索引作为键来检索枚举值的"名称",反之亦然。换句话说:PrimaryColors["Red"](或使用点表示法PrimaryColors.Red(将产生0PrimaryColors[0](点表示法在这里无效(将产生"Red" .

如果我们考虑三个概念,理解实现实际上并不难:

  1. 在javascript中将值分配给现有变量的计算结果为一个值(因此它是一个表达式而不是精神上的声明(
  2. 对象属性(键(可以通过给定键的括号访问
  3. 对象属性的类型需要为字符串或符号,但如果可能,其他值将传播到字符串。

因此:

PrimaryColors[PrimaryColors["Red"] = 0] = "Red";

相当于

const valueToBeUsedAsIndex = PrimaryColors.Red = 0; // assignment evaluates to 0, i. e. valueToBeUsedAsIndex has value 0
PrimaryColors[valueToBeUsedAsIndex] = "Red"; // PrimaryColors[0] is "Red". Technically this assignment yields a value too ("Red" in this particular case) but the value is discarded as it's not needed anymore
// at this point PrimaryColors looks like this: { Red: 0, "0": "Red" }

这里有很多很棒的答案,谢谢大家,但为了简单起见,我想添加更多内容,供我个人参考,对于其他在分解事情时具有相同学习结构的人,我将跳过立即调用的函数表达式 (IIFE( 病态图像,我们都已经知道那部分

现在让我一步一步地打破它

    PrimaryColors = {} // right now this is an empty object
    PrimaryColors[PrimaryColors["Red"]=0] = 'Red'

这里最重要的部分是许多人不知道当你为对象设置值时你得到一个返回值

像下面一样

   pp = {}
   dd = pp['red']=0
   0 // as you can see here the result of the assignment is returned
    //now dd is assigned this returned value 
    // this is the same thing going on here.
> dd
0

我们将返回值设置为键 0,JavaScript 哈希算法将其转换为字符串并作为字符串返回。

希望大家理解。