function级别范围和块级别范围之间的差异
我用JavaScript
编程了几个月,主要使用jQuery
。 我理解闭包并且我已经使用过它们,但是,我仍然无法理解其他语言(如C#)中 函数级别范围和块级别范围之间的区别 。 我一直在努力教自己,没有关于这个问题的结果。 有人可以用一些简单的例子来解释我吗?
在ES6(当前版本的JavaScript)之前,JavaScript只具有function级别范围。 即,以下内容:
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 }
完全等同于:
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 }
(事实上,我刚刚展示的内容称为“hoisting”,这正是JavaScript所做的:所有变量声明都被提升到函数的顶部;赋值保留在它们所在的位置。)
相比之下,像C#这样的语言具有块级范围 。 这会导致编译错误:
public void Foo() { if(true) { var foo = 1; Console.WriteLine("inside block: " + foo); } Console.WriteLine("outside block: " + foo); // WILL NOT COMPILE }
但你可以这样:
public void Foo() { var foo = 1; if(true) { foo = 2; Console.WriteLine("inside block: " + foo); // prints 2 } Console.WriteLine("outside block: " + foo); // prints 2 }
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( );
在上面的代码中,我们有一个名为inFor的变量,它在for循环中声明。 然后,我们尝试在alert语句中访问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 }
您可以在上面的代码中看到,变量y,i和inFor在if语句内或for循环内声明。 但是,即使这些变量是在那些单独的“块”中声明的,它们仍然可以在函数的其余部分中看到。 这是因为所有这些变量都在一个函数内声明 - 这就是函数范围的全部内容。
阻止范围与function范围
因此,如果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