我已经使用jQuery
几个月了,主要使用JavaScript
进行编程。 我理解闭包并且已经使用过它们,但是,我仍然无法理解其他语言(如C#)中的函数级别作用域和块级别作用域之间的区别。我一直试图自学,但在这个主题上没有结果。 有人能用一些简单的例子来解释一下吗?
我已经使用jQuery
几个月了,主要使用JavaScript
进行编程。 我理解闭包并且已经使用过它们,但是,我仍然无法理解其他语言(如C#)中的函数级别作用域和块级别作用域之间的区别。我一直试图自学,但在这个主题上没有结果。 有人能用一些简单的例子来解释一下吗?
在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
}
完全等同于:
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
}
事实上,我刚刚展示的称为“提升”,这正是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( );
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
}
{
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
function foo() {
console.log('before block: ' + bar); // ReferenceError: bar is not defined
if (true) {
let bar = 1; // bar is not let and not var
console.log('inside block: ' + bar); // prints 1
}
console.log('outisde block: ' + bar); // ReferenceError: bar is not defined
}
只是想让答案更完整。
var bar = 1
既是初始化又是声明。声明将被提升,而初始化则不会。此外,我不建议将w3schools作为学习资源;他们擅长SEO,但其他方面并不出色。 - Ethan Brown