本人第一篇博客,写的不好,请大家见谅!
说起js作用域有点诡异莫测的感觉,下面就详细说一下js作用域的问题。
想要理解js作用域,需要了解浏览器中的js解析器。js解析器读到<script></script>标签的时候就开始进行第一步:预解析
1)预解析:先找<script>标签内的关键字 var function等内容存储出来。
然后进行第二步:逐行读代码;
2)逐行读代码:一行一行读代码。
光说不练也不行,下面我们用代码解释一下:
<script>
alert(a);
var a = 1;
alert(a);
function a(){alert(2)}
alert(a);
var a = 3;
alert(a);
function a(){alert(4)}
alert(a);
</script>
对于这一段代码,我们分析一下:
第一步:预解析:也就是先读一下代码,找var 和function定义的变量,存入内存;预解析时候需要注意一下var的变量等号右边的内容不解析;
1):预解析到第二行的时候先存一个a,因为等号右边的内容不解析所以 a 的值是未定义(undefined);
2):解析到第四行的时候又存一个a,这个a是一个函数所以存入的是function a(){alert(2)},但是内存中已经存入了一个a,所以会替换掉存的a;(当内存中存的值是同名的时候函数的优先级大于变量)
3):以后都是一样的,所以内存中最后存入的是a 值是function a(){alert(4)};
第二步:逐行读代码:读第一句的时候a 值是function a(){alert(4)} 所以alert输出的是function a(){alert(4)} ;
读第二句的时候把1赋值给a,a的值是1,所以第三句的时候alert的是1;
第四句是一个函数,不执行,所以a的值不变,第五句alert值也是1
下面的都是这个样子,说道这里大家可能就会稍微理解了;
下面我们再说几个例子:
var a = 1;
function fn(){
alert(a);
var a = 2;
}
fn();
alert(a);
对于这个小程序来说;上面的知识同样适用,但是稍微也有一点不同,就是函数内部的问题,我们一点一点来说。
先预解析:函数外部存的a值为未定义,然后存了一个函数fn(){},在函数内部同样存了一个a 值也是未定义;
然后是读代码:第一句先把1赋值给外部的a,然后越过函数之后执行函数fn,执行函数时函数内部的a是未定义,所以函数执行的结果是一个未定义undefined,再读最后一句
alert一个1.
先说这么多吧!另外推荐大家可以看一下《Javascript权威指南》这本书,相信大家会有收获的!