JS的作用域,在你写一些函数的时候用处真的挺大的。大家跟着我的步伐来看一些其中的作用域的问题
对于JS来说其中对于JS来说其中包括至少两个步骤
(1)预解析【含有var,含有函数,其中含有参数】
a.其中找到的含有var的这里只是简单的找到了变量的名字,其中的变量的值是未定义的
b.其中在这里找到的函数则就是将其中的函数全部找到
(2)逐行解析【表达式:= + - * / % ++ -- ! 参数和函数调用】
其中有一些需要注意的点:
a.script是全局变量,全局函数。自上而下的
b.函数是局部的,由里向外
c.JSON也是局部的
d.其中的表达式可以改变其中的变量的值
接下来就看几个例子,彻底了解其中的一些比较666的东西
(1)
<script>
alert(a); //function a(){alert(4)};
var a=1;
alert(a); //1
function a(){alert(2)};
alert(a); //1
var a=3;
alert(a); //3
function a(){alert(4)};
alert(a); //3
</script>
看到这样的代码有没有觉得顿时感觉其中脑子有点混乱呢!那接下来就和我一块来分析一下吧?
第一步:预解析
a=undefine
function a(){alert(2)};
function a(){alert(4)};
在这里针对一个未定义的话,这里的a肯定就是函数的身份了。但是又因为后面的会覆盖前面的自此这里的a是第二个函数了
第二步:逐行解析
因为其中的表达式会改变其中的变量的值(指向),后面的会覆盖前面的,因此最后变量a就是代表的就是其中的数字3
(2)
<script>
var a=1;
function f1(){
alert(a); // 1
a=2;
}
f1();
alert(a); // 2
</script>
第一步:预解析
a=undefine
functionf1(){
alert(a);
a=2;
}
第二步:逐行解析
这里牵扯一个作用域链的问题,其中的局部的可以改变全局的,而且局部里面可以访问全局的,逐行解析的时候a被赋值为1
在f1函数被执行的时候 ,其中由于其中被执行的函数也算局部的环境因此这里也来进行二步曲
1.预解析 在函数这个环境里面什么也没有
2.逐行解析
(a)alert(a)这里因为局部的里面没有a,所以就会在全局环境里面找,这里就会找到全局的a,因此返回的是1.
(b)再下来就是一个a=2;这里是一个表达式,也是因为其中在局部里面没有a,所以这里就会找到全局里面,然后将全局里面的a的值改成2
(3)
<script>
var a=1;
function f1(){
alert(a); // undefine
vara=2;
}
f1();
alert(a); // 1
</script>
第一步:预解析
a=undefine
functionf1(){
alert(a);
vara=2;
}
第二步:逐行解析
1.给全局里面的a赋值为1
2.函数被执行:这里继续进行二步曲。
a.预解析
a=undefine
b.逐行解析(这里为什么没有改变全局a的值,原因是其中就近原则,局部里面有的绝对不去在全局里面找)
alert(a)的值是undefine
局部里面的a被赋值为2
3.访问的是其中的全局a因此返回的值是1
(4)
<script>
var a=1;
function f1(a){
alert(a); //undefine
a=2;
}
f1();
alert(a); // 1
</script>
1.这里需要注意的一点就是,函数里面进行了传参,相当于var a;但是这里函数被执行的时候,没有传入参数,相当于这里只是在局部里面创建vara=undefine;
2.这里a=2这一条来说,因为就近原则,在局部里面找到了a,因此这里给a进行了赋值,没有影响全局,因此最后访问a的时候,其中的值就是1
(5)
<script>
var a=1;
function f1(a){
alert(a); // 1
a=2;
}
f1(a);
alert(a); // 1
</script>
这里相对于前面不同的就是:这里函数被调用的时候进行了传参,var a=undefined;进行逐行解析的时候a=2