假设你有一个像这样的选择元素:
<select id="Stooge" name="Stooge">
<option value="0">Moe</option>
<option value="1">Larry</option>
<option value="2">Curly</option>
</select>
根据spec,当浏览器解析此页面时,它会创建一个全局范围的javascript变量window.Stooge
。到目前为止一切都很好。
在我的TypeScript代码中,我想以强类型方式引用选项,所以我有以下内容:
enum Stooge
{
Moe,
Larry,
Curly
}
这是像这样编译成javascript:
var Stooge;
(function (Stooge) {
Stooge[Stooge["Moe"] = 0] = "Moe";
Stooge[Stooge["Larry"] = 1] = "Larry";
Stooge[Stooge["Curly"] = 2] = "Curly";
})(Stooge || (Stooge = {})); <---error here
我的问题是:在每个浏览器除了 Safari之外,这都可以。但在Safari中,我收到以下错误:
YourFile.js:[Line X]TYPE_MISMATCH_ERR: DOM Exception 17: The type of an object was incompatible with the expected type of the parameter associated to the object.
这只发生在一个恰好与DOM元素同名的枚举上,我想这是因为两个定义之间存在冲突,除了这个相同的代码不会导致除Safari之外的任何错误。
那么,为什么它在其他浏览器中有效呢?有没有办法在Safari中解决这个问题? (我可以重命名enum或DOM元素,但如果可能的话,我想避免使用人工命名约定。)
答案 0 :(得分:2)
只要有可能,您应该避免在全球范围内放置任何内容。外部模块(很快将被重命名为更简单的名称,模块)是一种很好的方法。使用外部模块,您的enum
将被安全地隐藏在模块的范围内,不应与其他任何内容发生冲突。
另一种解决方案是使用常量枚举,将其转换为普通数字(即删除枚举类型)。例如,以下TypeScript:
const enum Stooge
{
Moe,
Larry,
Curly
}
var x = Stooge.Curly;
以下JavaScript中的结果:
var x = 2 /* Curly */;
您的最终选择是避免可能存在冲突的名称。将某些东西放在全球范围内时,尽可能减少碰撞风险是有帮助的。