关于范围:与JavaScript范围混淆

Confusion with JavaScript scoping

本问题已经有最佳答案,请猛点这里访问。

我对JavaScript作用域有相当的理解——语言具有函数级作用域,变量和函数声明被提升到其包含作用域的顶部。但是,我无法理解以下两段代码记录不同值的原因:

这会将值1记录到控制台:

1
2
3
4
5
6
7
8
var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
console.log(a);

奇怪的是,这条记录10:

1
2
3
4
5
6
7
var a = 1;
function b() {
    a = 10;
    return;        
}
b();
console.log(a);

那么引擎盖下面发生了什么?


我发现第一个例子更神秘…

在第二个示例中,您不会在函数内部声明变量a。所以当你分配给a时,它的目标是外部的a。挺直的。

在第一个示例中,您在函数内部声明一个变量a,但使用了一种不同寻常的方式:声明一个名为a的函数。因此,给a赋值将使用该局部"变量"。

这里有两件事要做:

a)变量和函数声明被"提升"到其范围的顶部。当function a(){}写在末尾附近时,保存它的变量a已经创建并在作用域顶部可见。

b)函数也可用作变量。您可以传递函数,也可以重新分配函数定义。它们与其他变量共享相同的名称空间。


这是因为当使用声明的function时,它会被提升并转换为函数表达式,即var a = function() {};,这会与a变量产生冲突。


您可以使用Visual Studio进行编码:

enter image description here

在typescript文件中编程代码将使您能够通过悬停变量来查看变量类型。

enter image description here

当您试图将数值10应用于第一次声明为函数的变量"A"时,它还会警告您。这就是我喜欢的关于typescript的东西,你可以在这里得到更多关于它的信息:http://www.typescriptlang.org/


javascript是基于解释器的。javascript {block}没有作用域,但是函数有作用域。

在你的例子中,

1
2
3
4
5
6
7
8
var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
console.log(a);

首先,您将a指定为整数10,但在最后,您将a重新指定为将在作用域结束时消失的函数。

在本代码中,

1
2
3
4
5
6
7
8
var a = 1;
function b() {
    a = 10;
    return;
    function foo() {}
}
b();
console.log(a);

你的a没有被替换,返回到全局范围,它会记录10