虽然,ES6在我们工作中应用得越来越广泛,但是还是很多项目保留着ES5的写法,所以,今天,带着大家重新巩固下ES5下的作用域及预解析机制。
作用域:域,指的是一个空间、范围、区域,作用指的是在域内可进行读写操作。一个变量的作用域是程序源代码中定义的这个变量的区域。
在ES5中,只存在全局和函数级作用域,在ES6中,引入了块级作用域,js的预解析机制大概分为两个过程:预解析和自上而下逐行解读
预解析:js解析器会先把var定义的变量、function、参数等一些东西存储进仓库里面(内存)。变量var在正式运行之前,都赋值为undefined,function函数在运行之前,就是整个函数块
表达式=、+、-、*、/、++、--、!、%.....number()、参数都可以赋值
遇到重名的,只留下一个,变量和函数重名,函数优先级高于变量,只留下函数
函数调用(函数是一个作用域,遇到作用域都会按照先进行预解析,然后逐行解读的过程执行),先局部找参数,局部找不到就自下向上找(作用域链)
概念扯了一大段,估计初学者还是有点晕乎乎,老司机就可以提前下车了,接下来,咋们举几个小栗子,结合上面的理论,深入理解。
例1:
alert(a); //error: a is not defineda = 3;
分析:
预解析
上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:
整个作用域没有找到var function 参数
逐行解读
预解析后,内存中存在a且被赋值了underfind整个变量,所有,代码执行过程中程序直接报错。
例2:
alert(a); //undefinedvar a = 3;
分析:
预解析
上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:
执行到第二行时,a 的值是未定义。
逐行解读
第一行:预解析后,内存中存在a且被赋值了underfined
例3:
alert(a); // function a (){ alert(4); }var a = 1;alert(a); // 1function a (){ alert(2); }alert(a); // 1var a = 3; alert(a); // 3function a (){ alert(4); }alert(a); // 3
分析:
域解析
上面说过,预解析时只会把var 、 function 、参数等存储起来,所以:
执行到第二行时,a 的值是未定义。
执行到第四行时,a 的值是函数本身,也就是function a(){alert(2);}。
执行到第六行时,a 的值还是第四行时的值,也就是function a(){alert(2);},因为函数的优先级比变量高。
执行到第八行时,a 的值就变成了function a(){alert(4);} ,因为当两个函数重名时,遵循代码从上往下执行。
新闻热点
疑难解答
图片精选