17

以下打字稿:

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 在做什么。
括号中的函数是使用另一个赋值作为索引/键来分配字符串值。我以前从未见过这样的事情。
函数后面的 (PrimaryColors || (PrimaryColors = {}) 的目的是什么?
如果答案是正确学习 JavaScript,我会欣然接受它,只要它附带一个可以清楚解释我所看到内容的建议来源这里。

4

5 回答 5

18

我相信:

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最初是未定义的(假),所以它会传递{}给函数。

PrimaryColors || (PrimaryColors = {})
于 2013-11-29T03:59:35.520 回答
9

也许这会有所帮助。

(function() {})();

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

var x = y || y = {};

如果将某些东西初始化为默认值的常见模式。如果 y 没有值,则 or 语句的第一部分为假,因此它执行第二部分,为 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;
于 2013-11-29T04:06:48.657 回答
5

我发现了这个问题,因为我想知道当你可以立即初始化 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";
// ...

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

于 2016-09-11T12:38:22.363 回答
0

这里有很多很好的答案,谢谢大家,但为了简单起见,我想添加更多内容供我个人参考,对于其他在分解到最后一点方面具有相同学习结构的人,我将立即跳过 -调用函数表达式 (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 哈希算法将其转换为字符串并作为字符串返回。

我希望每个人都能理解。

于 2022-02-19T19:16:43.763 回答
0

它用于创建关联映射(换句话说,对象),您将在其中使用索引作为键检索枚举值的“名称”,反之亦然。换句话说:(PrimaryColors["Red"]PrimaryColors.Red使用点符号)将产生0. PrimaryColors[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" }
于 2019-12-09T23:06:30.307 回答