一、引言
Echosong 用的东西比较杂,对各种脚本语言都有些涉猎。在来回切换间隙 难免被一些东西混淆。 其中变量作用域就是一个很容易混淆的东东。
下面把这些脚本的作用域做一个总结。以用备忘。
二、详细分析各个脚本语言作用域
1、php
A、局部变量
函数体内部的变量,适用范围为函数体内
<?php
$a = "funcotn外部";
functon local(){
$a = "local内部";
echo $a;
}
local(); //local内部
echo $a; //functoin外部
?>
B、全局变量
全局变量是指在程序任何地方都能使用的变量,php将一个变量申明为全局变量在其前面加 "global" 关键字
<?php
$a = "funcotn外部";
functon local(){
global $a ;
global $b;
$b = "全局的b变量";
echo $a;
}
local(); //functoin外部
echo $b; //全局的b变量
?>
另外有静态变量 他可能有点跟作用域关系,但是它解决的是变量生命周期问题,不在作用域讨论范围
2、python
几个概念:
python能够改变变量作用域的代码段是def、class、lamda.
if/elif/else、try/except/finally、for/while 并不能涉及变量作用域的更改,也就是说他们的代码块中的变量,在外部也是可以访问的
变量搜索路径是:本地变量->全局变量
python能够改变变量作用域的代码段是def、class、lamda.
[python] view plaincopyprint?
def scopetest():
localvar=6;
print(localvar)
scopetest()
#print(localvar) #去除注释这里会报错,因为localvar是本地变量
if/elif/else、try/except/finally、for/while
[python] view plaincopyprint?
while True:
newvar=8
print(newvar)
break;
print(newvar)
try:
newlocal=7
raise Exception
except:
print(newlocal)#可以直接使用哦
输出结果:8 8 7
可见这个关键字中定义变量,他们的作用域跟外部是一致的,这个跟Java的作用域概念有点不一样。
变量搜索路径是:本地变量->全局变量
[python] view plaincopyprint?
def scopetest():
var=6;
print(var)#
var=5
print(var)
scopetest()
print(var)
输出结果:5 6 5
这里var 首先搜索的是本地变量,scopetest()中 var=6相当于自己定义了一个局部变量,赋值为6. 当然如果的确要修改全局变量的值,则需要如下:
[python] view plaincopyprint?
def scopetest():
global var
var=6;
print(var)#
var=5
print(var)
scopetest()
print(var)
输出结果:5 6 6
再看一种这种情况:
[python] view plaincopyprint?
def scopetest():
var=6;
print(var)#
def innerFunc():
print(var)#look here
innerFunc()
var=5
print(var)
scopetest()
print(var)
输出结果:5 6 6 5
根据调用顺序反向搜索,先本地变量再全局变量,例如搜先在innerFunc中搜索本地变量,没有,好吧,找找调用关系上一级scopetest,发现本地变量var=6,OK,就用他了。
3、javascript
1)javascript的作用域链
示例:
<script type="text/javascript">
var x=1;
function main(){
var y=2;
function second(){
var z=3;
alert(y);
}
second();
}
main();//2
</script>
作用域链:javascript需要查询一个变量y时,首先会查找作用域链的第一个对象,如果第一个对象没有定义x变量,javascript会继续查找有没有定义x变量,如果第二个对象没有定义则会继续查找,以此类推。
上面的代码涉及三个作用域对象,依次是second,main,window.
(2)函数体内部,局部变量的优先级比同名的全局变量高。
示例:
<script type="text/javascript">
var a=100;//定义全局变量
function main(){
var a=1;//定义局部变量
alert(a);
}
main();//1
alert(a);//100
</script>
(3)javascript没有块级作用域(表示在javascript中,函数不仅在块中有定义,在整个函数都有定义。)
示例:
<script type="text/javascript">
function main(){
var a = 1;
if(1){
var b=0;
for(var c=0;c<3;c++){
alert(c);//0 1 2
}
alert(c);//3
}
alert(b);//0
}
main();
</script>
(4)函数中声明的变量在整个函数中都有定义。(表示如果函数内部有定义变量,即使在定义之前输出但会先执行后面定义语句,然后判断输出结果,所以说声明的变量在整个函数中都是起作用的。)
示例:
<script type="text/javascript">
var a = 1;
function rain(){
alert(a);//undefined
var a = 100;//相等于先定义 后初始化 var a; a=100;
alert(a);//100
}
rain();
</script>
(5)未使用var关键字定义的变量都是全局变量。
示例:
var a=100;
function main(){
b=1;
alert(b);
}
main();//1
alert(b);1
(6)全局变量都是window对象的属性。
示例:
<script type="text/javascript">
var a=100;
function main(){
alert(window.a);
}
main();//100
alert(a);//100
</script>
4、vbscript
<%
dim a,b
a = 10
b = 20
Function testFun()
response.Write ("值"&a) '值:10
response.write ("值"&b)'值 20
dim a
a = 2
response.Write ("值"&a) '值2
response.write ("值"&b) '值20
End Function
Call testFun()
%>
从注释结果来看vbscript 作用域类似于javascript 值不过 vbscript 不存在var关键字。
也不存在作用域链。 所有的变量都是dim。 也就是说 函数里面是不可以定义全局变量
三、总结对比
1、这些脚本语言有个共同特点都是没有块级作用域
2、都具有函数作用域