为什么typescript允许在声明变量之前使用变量?

时间:2013-06-24 11:01:46

标签: javascript typescript

Typescript不会为以下代码提供编译器错误:

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

var a = 10;

alert(b.toString());

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

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

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

2 个答案:

答案 0 :(得分:11)

因为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类型(它不知道您在赋值之前使用它,因为{{1}隐式设置类型)。 TypeScript认为它是一个数字,即使它不是,因为它的声明。

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

答案 1 :(得分:6)

假设您了解您的代码等同于:

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 必须允许这样做。