# 关于"JavaScript变量作用域"的试验
# 先说结论
JavaScript 中, 强烈建议声明变量时使用 var
.
不使用 var
似乎也可以声明变量, 但是本质上是有区别的:
- 带
var
表示"在当前作用域下声明变量, 并且赋值"; - 不带
var
则会冒泡寻找(由内往外寻找)需要赋值的对象, 从而会污染全局变量;
PS. 如果要了解本质原因, 可以参考 <<代码之髓>> (opens new window) 的第 7 章: 本质原因是 JavaScript 把用
var
声明的变量视为"静态作用域", 而把没有任何声明的变量视为"全局作用域".
# 试验 01 -- 用var声明变量
window.str = 'GuangDong';
function t1(){
var str = 'GuangZhou';
function t2(){
var str = 'FoShan';
alert(str);
}
t2();
}
t1();
alert(window.str);
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
输出结果:
FoShan
GuangDong
1
2
2
# 试验 02 -- 冒泡寻找
window.str = 'GuangDong';
function t1(){
var str = 'GuangZhou';
function t2(){
alert(str);
}
t2();
}
t1();
alert(window.str);
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
输出结果:
GuangZhou
GuangDong
1
2
2
分析: t2()
函数里面的str
变量没用var
, 所以只是"赋值", 会往外冒泡寻找需要赋值的变量.
发现t1()
函数的var str = 'GuangZhou'
, 所以alert('GuangZhou')
做为对比, PHP如果没有声明str
, 会报错:
$str = 'GuangDong';
function t1(){
$str = 'GuangZhou';
function t2(){
echo $str;
}
t2();
}
t1();
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
这个PHP的demo会报错:
PHP Notice: Undefined variable
# 试验 03 -- 冒泡寻找
window.str = 'GuangDong';
function t1(){
function t2(){
alert(str);
}
t2();
}
t1();
alert(window.str);
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
输出结果:
GuangDong
GuangDong
1
2
2
分析: alert(str)
在t2()
内部找不到str
变量, 冒泡往外寻找,
在t1()
也找不到str
变量, 继续冒泡往外寻找,
发现全局变量window.str
,
所以输出GuangDong
.
# 试验 04 -- 全局变量被污染
window.str = 'GuangDong';
function t1(){
function t2(){
str = 'FoShan';
alert(str);
}
t2();
}
t1();
alert(window.str);
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
输出结果:
FoShan
FoShan
1
2
2
分析: t2()
里面的str
变量没有使用var
, 所以会冒泡往外寻找, 一直找到window.str
, 将其赋值为FoShan
.
所以输出全局变量alert(window.str)
时, 输出FoShan
.
# 参考文章
- <<代码之髓>> (opens new window) 第 7 章 -- 名字和作用域