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

Javascript 为什么typescript允许在声明变量之前使用它?,javascript,typescript,Javascript,Typescript,Typescript不会为以下代码提供编译器错误: var b = a + 10; // Why no compilation error here var a = 10; alert(b.toString()); 我希望第一行是一个错误,因为直到现在我还没有声明或初始化var a 如果删除第二行,则会出现编译器错误 我知道它在JavaScript中是有效的,但我希望TypeScript会给我编译错误或警告。,因为它可能会让人困惑。你的代码实际上意味着 var a, b b = a +

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

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

var a = 10;

alert(b.toString());
我希望第一行是一个错误,因为直到现在我还没有声明或初始化var a

如果删除第二行,则会出现编译器错误

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

,因为它可能会让人困惑。你的代码实际上意味着

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中的每个变量都有一个在变量生命周期内无法更改的类型,在您的情况下,
a
number
type(它不知道您在赋值之前使用它,因为
var
隐式设置类型)。TypeScript假定它是一个数字,即使它不是,因为它的声明


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

假设您了解您的代码相当于:

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是一个可以赋值和读取的变量的有效值

在各种用例中,此功能是有价值的。例如,typescript中使用的模块模式:

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开发人员需要底层JavaScript语言的强大功能


对于赋值前阅读无效的语言(例如C#),情况并非如此。在C#中,未赋值变量没有意义。在JavaScript中是这样的。所以TypeScript必须允许这样做

因为变量声明被挂起?我已经解释了为什么TypeScript必须允许它。这是因为您可能需要执行
var x=undefined
,而在C#中,未赋值变量没有意义。在JavaScript中是这样的。所以TypeScript必须允许这种情况。我已经向你们展示了一些案例,你们实际上需要这种“愚蠢的东西”。例如模块模式。如果TypeScript剥夺了JavaScript的强大功能,那就太糟糕了!这不是在保护我。它允许我这样做。我不想要。我不太确定你的函数示例。虽然很明显,
a
引用了
b
,但函数体在调用
a
之前不会进行评估。所以,这与提升IMO没有任何关系。下面是我的意思的一个例子:。尽管
foo
在定义时不存在且未被提升(因为没有变量声明),但只要在
a
之前调用
b
,则不会引发错误。
var a:number = undefined; // same as simply "var a" 
console.log(a);