JS作用域的理解

JS作用域的理解

理解JS函数的作用域有助于我们分析函数执行,调用。

什么是作用域?

JS的函数作用域,将作用域拆开来看,“作用”表示读写操作,函数可以读取代码,改写代码;“域”表示空间,范围,区域。一般指在

函数作用于的操作流程

函数在执行的时候,至少会发生这两件事。第一是预解析,第二是逐行解读代码。

预解析:函数在执行的时候,会读取到整个函数内的关键字或参数。比如var、function、参数。读取过程中并不会读取到等号右边的代码。也就是说当读取到var的时候,其实是一种未定义的状态,读取到function的时候,是将整个函数全部提取; 逐行解读代码:预解析之后,就来逐行解读代码,执行代码;当在逐行解读的时候,如果碰到函数调用,那么就会先解读函数内部的代码块,这个时候就又会遵循函数作用域的执行过程。先解析,再解读。其中就涉及到全局变量和局部变量的操作。 逐行解读代码的一些原则:

1、逐行解读过程中,当碰到表达式的时候,就会用表达式修改预解析的值;表达式是=、+、-、*、/、参数(注意,参数也是表达式,参数可以被修改)

2、预解析的时候,遇到重名的变量名称,字母,值留下一个;

3、预解析时,当变量碰到函数的名称一致的时候,值留下函数块。因为预解析的时候,变量其实是未定义的状态

4、逐行解读代码时,碰到函数,如果没有调用,表示函数没有执行。此时直接略过,直到有表达式才能改变变量的值。

5、所有变量,在正式运行代码之前,都会提前赋一个值;未定义。所有函数,在预解析的时候,都是函数块;

6、逐行解读代码时,是从上到下,从函数内部到函数外部的执行过程

简单案例:

<script type="text/javascript">
   alert(a);
  var a=1;//undefined
</script>
<script type="text/javascript">
  var a=1;
  alert(a);//弹出1
</script>

以上这两段代码,只是调换了一下顺序,执行的结果就不相同。分析一下它们的执行过程 第一段代码:1、解析器先找到

2、然后逐行解读代码,从上到下,先解析了alert的代码,并执行,这个时候a还是属于一种未定义的状态,因此弹出了undefined;

第二段代码:1、解析器先找到

2、逐行解读代码。从上到下,var a=1,为a进行了赋值,此时a=1,再解读alert(a)的值,那么最后弹出1.

复杂的案例:

alert(a);                
var a = 1;
alert(a);                  
function a (){ alert(2); }
alert(a);               
var a=3;     
alert(a);                   
function a (){ alert(4); }
alert(a);

上述这行代码,比较复杂,但我们依然按照作用域的解析过程来分析分析

1、预解析。找到关键字var和function。 从上到下,依次预解析的值有变化。先是第二行代码,var a是一种未定义;然后是第四行代码,是一个函数,此时函数a的值就覆盖了第二行代码的未定义;第六行变量依旧是未定义,修改不了;第八行是一个函数,此时就将第四行的函数块修改了。最后预解析保存的是第八行代码:function a (){ alert(4); }

2、逐行解读。

2-1、预解析过程后保存的代码是函数块,a=function a(){alert(4)},此时执行第一行代码,alert(a),那么就会弹出第八行代码。function a(){alert(4)}

2-2、解读第二行代码,a=1,此时将函数代码块修改了,a=1,那么第三行代码则会弹出1;

2-3、解读到第四行代码,是一个函数,没有调用,也就没有表达式,直接跳过执行第五行代码,依然是a=1;

2-4、执行第六行代码,是一个表达式,将a修改为3;那么第七行代码就会弹出一个3

2-5、执行到第八行代码时,是一个函数块,依旧没有调用,直接跳过执行第九行代码,所有最后弹出依旧是3

所以最后的结果是:

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

如果在最后再调用a()的话,会怎么样呢?答案是报错。因为最后执行的结果是一个a=3,是一个数字类型。用函数调用产生报错。 作用域的执行过程中,先找到整个作用域内的关键字或参数;然后再逐步解析。碰到调用的函数,我们根据执行顺序,再去解析被调用的函数块内部的代码。 当我们碰到函数作用域的时候,就有全局变量和局部变量之分,进而产生闭包和作用域链的知识。我们将会在后续陆续讨论。


  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值