功能级别范围和块级别范围之间的差异

Dim*_*imt 7 javascript c# scope function

我已经编程JavaScript了几个月,主要是使用jQuery.我理解闭包并且我已经使用过它们,但是,我仍然无法理解其他语言(如C#)中函数级别范围和块级别范围之间区别.我一直在努力教自己,没有关于这个问题的结果.有人可以用一些简单的例子来解释我吗?

Eth*_*own 14

在ES6(当前版本的JavaScript)之前,JavaScript只具有功能级别范围.即,以下内容:

function foo() {
    console.log('before block: ' + bar);      // prints 'undefined'
    if(true) {
        var bar = 1;
        console.log('inside block: ' + bar);  // prints 1
    }
    console.log('outisde block: ' + bar);     // prints 1
}
Run Code Online (Sandbox Code Playgroud)

完全等同于:

function foo() {
    var bar;
    console.log('before block: ' + bar);      // prints 'undefined'
    if(true) {
        bar = 1;
        console.log('inside block: ' + bar);  // prints 1
    }
    console.log('outisde block: ' + bar);     // prints 1
}
Run Code Online (Sandbox Code Playgroud)

(事实上​​,我刚刚展示的内容称为"吊装",这正是JavaScript所做的:所有变量声明都被提升到函数的顶部;赋值保留在它们所在的位置.)

相比之下,像C#这样的语言具有块级范围.这会导致编译错误:

public void Foo() {
    if(true) {
        var foo = 1;
        Console.WriteLine("inside block: " + foo);
    }
    Console.WriteLine("outside block: " + foo);  // WILL NOT COMPILE
}
Run Code Online (Sandbox Code Playgroud)

但你可以这样:

public void Foo() {
    var foo = 1;
    if(true) {
        foo = 2;
        Console.WriteLine("inside block: " + foo);  // prints 2
    }
    Console.WriteLine("outside block: " + foo);     // prints 2
}
Run Code Online (Sandbox Code Playgroud)

  • @EthanBrown你误读了OP的注释 - 外部作用域无法访问_inner function_中声明的变量. (2认同)

vin*_*o20 5

function scopeTest() {

/* consider this simple for loop
    to be the "block" that we were
    talking about earlier
*/
for (var i = 0; i <= 5; i++)
{
  var inFor = i; 
}

alert(inFor);  // what happens here?

}


// call the function defined above
scopeTest( );
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我们有一个名为 inFor 的变量,它是在 for 循环中声明的。然后,我们尝试在警报语句中的 for 循环之外访问 inFor 变量。

如果上面的代码没有发出任何警报,那么我们就知道这是因为 Javascript 使用块作用域。在块作用域语言中,变量 inFor 在 for 循环之外不可见。这意味着如果 Javascript 是块作用域语言,则调用“alert(inFor);” 将无法识别 inFor 变量,并且不会向警报框输出任何内容。

但是,上面的代码实际上输出了“5”,这意味着 inFor 变量确实存在于 for 循环之外,这必然意味着 Javascript 没有块作用域。我们的答案是——Javascript 没有块作用域。

function scopeTest() {

var x = 2;

//this is always true:
if(x == 2)
{
  var y = 15;
  for (var i = 0; i <= 5; i++)
  {
    var inFor = i; 
  }
} 

  console.log(y); // y is defined, prints 15   
  console.log(i);  // i is defined, prints 6
  console.log(inFor);  // inFor is defined, prints 5

}
Run Code Online (Sandbox Code Playgroud)

您可以在上面的代码中看到变量 y、i 和 inFor 是在 if 语句内或 for 循环内声明的。但是,即使这些变量是在这些单独的“块”内声明的,它们仍然对函数的其余部分可见。这是因为所有这些变量都是在一个函数内声明的 - 这就是函数作用域的全部内容。

块作用域与函数作用域

那么,如果 Javascript 不使用块作用域,那么它使用什么样的作用域呢?

好吧,Javascript 使用了一种叫做函数作用域的东西。

基本上,函数作用域和块作用域之间的区别在于,在使用函数作用域的语言中,函数内声明的任何变量在同一函数内的任何位置都可见。但对于块作用域,变量的可见性仅限于用大括号括起来的任何给定块(无论是 if 语句、where/for 循环等)。

http://www.programmerinterview.com/index.php/javascript/javascript-block-scope/ http://www.programmerinterview.com/index.php/javascript/javascript-function-scope/

    {
     here you can't access both a and b
     var a=1
     here you can access only a
        {
        here you can access only a
        var b=3
        here you can access both a and b
        {
        here you can access both a and b
        }
        here too you can access both a and b
        }
        here you can access only a
        }
       here you can't access both a and b
Run Code Online (Sandbox Code Playgroud)