【问题标题】:Why does typescript allow variable to be used before declaring it?为什么打字稿允许在声明变量之前使用它?
【发布时间】:2013-06-24 11:01:46
【问题描述】:

Typescript 没有给出以下代码的编译器错误:

var b = a + 10; // Why no compilation error here

var a = 10;

alert(b.toString());

我希望第一行是一个错误,因为直到此时我还没有声明或初始化 var a。

如果我删除第二行,我会收到编译器错误。

我知道它在 JavaScript 中有效,但我希望 TypeScript 会给我编译错误或警告。

【问题讨论】:

  • 因为变量声明被提升了?
  • 我已经解释了为什么 TypeScript必须 允许它。这是因为你可能需要做var x = undefined
  • 而在 C# 中,未赋值的变量没有意义。在 JavaScript 中确实如此。所以 TypeScript 必须允许这样做。
  • 我已经向你展示了你真正需要这个“愚蠢的东西”的案例。例如模块模式。如果 TypeScript 夺走了 JavaScript 的力量,那就太糟糕了!

标签: javascript typescript


【解决方案1】:

因为hoisting behavior 可能会造成混淆。您的代码实际上意味着。

var a, b

b = a + 10
a = 10

alert(b.toString())

允许提升是有正当理由的,但它们不涉及var,而是function - 您可以调用稍后声明的函数。

alert(identity(i))

function identity(i) {
    return i
}

在这种情况下,alert 使用稍后声明的函数的结果。由于提升行为,它可以工作。

虽然我同意这个案例应该有一个警告(不是错误,TypeScript 希望与 JavaScript 兼容),但 TypeScript 目前似乎没有注意到这一点。 TypeScript 中的每个变量都有一个在变量生命周期内不能更改的类型,在您的情况下,anumber 类型(它不知道您在分配之前使用它,因为 var 隐式设置类型)。 TypeScript 假定它是一个数字,即使它不是,因为它的声明。

您可能希望将此作为 TypeScript 中的错误报告。

【讨论】:

  • 它没有保护我。它允许我这样做。我不想要。
  • 我不太确定你的函数示例。虽然很明显a 引用了b,但直到调用a 才评估函数体。因此,这与提升 IMO 无关。这是我的意思的一个例子:jsfiddle.net/fJ9RV。虽然foo在定义的时候不存在也没有被提升(因为没有变量声明),但是不会抛出错误,只要在a之前调用b就可以了。
【解决方案2】:

假设你理解你的代码相当于:

var a, b
b = a + 10
a = 10
alert(b.toString())

这又相当于:

var a = undefined, b = undefined
b = a + 10
a = 10
alert(b.toString())

应该允许它的原因是因为 undefined 是一个可以分配和读取的变量的有效值。

有多种使用案例表明此功能很有价值。例如打字稿中使用的模块模式:

module x{
    export var foo; 
}

利用这一事实生成 javascript 代码:

var x;
(function (x) {
    x.foo;
})(x || (x = {})); //x was never assigned but used in "x ||" part

由于 JavaScript 向后兼容性,它被留在 TypeScript 中(更不用说它很有用)。

这是一个纯粹的 TypeScript 用例。也许您想将 undefined 传递给函数调用 (this is valid typescript):

var a:number = undefined; // same as simply "var a" 
console.log(a);

只是假设 TypeScript 开发人员想要底层 JavaScript 语言的强大功能。

这不适用于在分配前阅读无效的语言(例如 C#)。在 C# 中,未赋值的变量没有意义。在 JavaScript 中确实如此。所以 TypeScript 必须允许这样做。

【讨论】:

    猜你喜欢
    • 2015-02-20
    • 2014-09-15
    • 1970-01-01
    • 1970-01-01
    • 2020-09-29
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 2017-12-17
    相关资源
    最近更新 更多