JavaScript全面了解作用域(基础、this、闭包、继承)之一
JavaScript作用域总体来说,还是非常重要的。每一段JS都有作用域链,从低向上搜索。
第一部分:作用域链
view plain
<html>
<head>
<script >
var p="first";
function getp()
{
var p="second";
document.write(p);
}
document.write(p+"\n");
getp();
</script>
</body>
</html>
第一步,我们先确定所在的作用域。第九行处于window里面。第十行处于getp()
第二步,从下搜索,一直搜索到顶层。
我们可以先总结一下:作用域链从下向上搜索,一直搜索到或者顶层。我们很容易明白,函数作用域高于全局定义域。全局变量其实就是window下面的变量。
另外我们看下面的一个小例子,比较有意思。
<script defer>
var a="global a\n";
function changeA()
{
document.write(a);
var a="function a\n";
document.write(a);
}
changeA();
document.write(a);
</script>
<script defer>
var a="global a\n";
function changeA()
{
document.write(a);
var a="function a\n";
document.write(a);
}
changeA();
document.write(a);
</script>
结果是什么呢?undefinedfunction a global a,真是想不到呀。 www.zzzyk.com
解析器,先解析作用域链,也就是说函数运行之前,作用域链已经形成。在函数运行的时候,知道a在函数内部,然后在函数里面需找,但是没有需找到,就变成未定义了。
第二部分:块作用域
JS当中没有块作用域。我们先举个C++例子
#include <iostream>
using namespace std;
int main()
{
int a=1;
if(true)
{
int a=2;
cout<<a<<endl;
}
cout<<a<<endl;
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int a=1;
if(true)
{
int a=2;
cout<<a<<endl;
}
cout<<a<<endl;
return 0;
}
结果是2 1,这就是块作用域。但是在JS呢?
<script >
var a=2;
if(true)
{
var a=1;
document.write(a);
}
document.write(a);
</script>
<script >
var a=2;
if(true)
{
var a=1;
document.write(a);
}
document.write(a);
</script>
结果是11,可以看出不同点了吧,相当于重复定义了。
下面评论的朋友,没有看懂我的意思,我在这里修改一下。为什么是var a=1;不是a=1;
我的目的测试是否拥有块作用域。如果他的结果和C++一样,说明外面作用域取不到块作用域值,这是有块作用域的,否则,你能改变外界的作用域链,说明是没有的。
如果是按照下面那位兄弟说的话,无论是否拥有块作用域,他的结果都是11。就无法判断是否有块作用域之说了。
第三部分:局部定义
<script >
function a()
{
var a=1;
b=2;
}
a();
document.writeln(a);
document.writeln(b);
</script>
<script >
function a()
{
var a=1;
b=2;
}
a();
document.writeln(a);
document.writeln(b);
</script>
结果是function a() { var a=1; b=2; } 2。还有弹出一个错误。
解释一下,a没有定义,b=2;
透过现象看本质,a不是全局变量,b是。
结论是如果不写var的话,他就变成一个全局变量。
摘自 WebGIS,一步一步踏实走出来
补充:web前端 , JavaScript ,