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
}
3条答案
按热度按时间9njqaruj1#
在ES6(JavaScript的当前版本)之前,JavaScript只有函数级作用域,即:
完全等同于:
(As事实上,我刚才展示的东西叫做“提升”,这正是JavaScript所做的:所有变量 * 声明 * 都被提升到函数的顶部;作业保留在原来的位置。)
相反,像C#这样的语言有 * 块级作用域 *,这会导致编译错误:
但你可以拥有这个:
zf9nrax12#
在上面的代码中,我们在for循环中声明了一个名为inFor的变量,然后我们尝试在alert语句中访问for循环之外的inFor变量。
如果上面的代码没有提示任何东西,那么我们知道这是因为Javascript使用了块作用域。在块作用域语言中,变量inFor在for循环之外是不可见的。这意味着如果Javascript是块作用域语言,那么对"alert(inFor); "将无法识别inFor变量,并且不会向警报框输出任何内容。
但是,上面的代码实际上输出了一个"5",这意味着inFor变量确实存在于for循环之外,这一定意味着Javascript没有块作用域。这就是我们的答案-Javascript没有块作用域。
在上面的代码中,你可以看到变量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/
yb3bgrhw3#
继续@Ethan Brown的回答,如果我们使用let或const代替var,我们会得到“referenceError”,因为let和const是块作用域的。
只是想让答案完整。