关于块级作用域 |
static void Main(string[] args)
{
if(true)
{
int num = 10;
}
System.Console.WriteLine(num);
}
这段代码如果进行编译,是无法通过的,因为"当前上下文中不存在名称num". 因为这里变量的作用域是由花括号限定的,称为块级作用域.
在块级作用域下,所有的变量都在定义的花括号内,从定义开始到花括号结束这个
范围内可以使用. 出了这个范围就无法访问. 也就是说如下代码
if(true)
{
int num = 10;
System.Console.WriteLine(num);
}
//这里可以访问,因为变量的定义与使用在同一个花括号内.
JavaScript中的作用域 |
在JavaScript中,下面代码:
if(true) {
var num = 10;
}
alert(num);
运行的结果是弹窗10. 那么在JavaScript中变量的作用范围是怎么限定的呢?
- 函数限定变量作用域
在JavaScript中,只有函数可以限定一个变量的作用范围. 什么意思呢?就是说,在JavaScript中,在函数里面定义的变量,可以在函数里面被访问,但是在函数外无法访问. 看如下代码:
var func = function() {
var num = 10;
};
try {
alert(num);
} catch ( e ) {
alert( e );
}
这段代码运行时,会抛出一个异常,变量num没有定义. 也就是说,定义在函数中的变量无法在函数外使用,当然在函数内可以随意的使用, 即使在赋值之前. 看下面代码:
ar func = function() {
alert(num);
var num = 10;
alert(num);
};
try {
func();
} catch ( e ) {
alert( e );
}
从这里可以看得出,变量只有在函数中可以被访问. 同理在该函数中的函数也可以访问
- 子域访问父域
前面说了,函数可以限定变量的作用域,那么在函数中的函数就成为该作用域的子域. 在子域中的代码可以访问到父域中的变量. 看下面代码:
var func = function() {
var num = 10;
var sub_func = function() {
alert(num);
};
sub_func();
};
func();
这段代码执行得到的结果就是 10. 可以看到上文所说的变量访问情况. 但是在子域中访问父域的代码也是有条件的. 如下面代码:
var func = function() {
var num = 10;
var sub_func = function() {
var num = 20;
alert(num);
};
sub_func();
};
func();
这段代码比前面就多了一个"var num = 20;",这句代码在子域中,那么子域访问父域的情况就发生了变化,这段代码打印的结果是 20. 即此时子域访问的num是子域中的变量,而不是父域中的.
由此可见,访问有一定规则可言. 在JavaScript中使用变量,JavaScript解释器首先在当前作用域中搜索是否有该变量的定义,如果有,就是用这个变量;如果没有就到父域中寻找该变量. 以此类推,直到最顶级作用域,仍然没有找到就抛出异常"变量未定义". 看下面代码:
(function() {
var num = 10;
(function() {
var num = 20;
(function(){
alert(num);
})()
})();
})();
这段代码执行后打印出20. 如果将"var num = 20;“去掉,那么打印的就是10. 同样,如果再去掉"var num = 10”,那么就会出现未定义的错误.