作用域:什么样的空间去读和写
域:空间、范围、区域。。。
<script> 全局变量 全局函数 一个<script>就是一个域
作用:读、写
<script> alert(a); //结果是Undefined var a=1 </script>
为什么?
<script> alert(a); //直接报错 a=1 </script>
为什么?
浏览器内部专门读取JS文件的程序:“JS解析器”
作用域="JS解析器"的工作方式
<script> alert(a); var a=1; function fn1(){ alert(2); } </script>
至少有两步:
1) "找一些东西": var function 参数;
上面那个代码预编译(预解析) :找到 var function;
var a=undefined (可以理解为没有逐行运行代码之前的所有的var都是提前赋值未定义,偷懒的机制)
fn1=funciton fn1(){alert(2)} (所有的函数,在正式运行代码之前,都是整个函数块)
把找到的var fn1放入一个仓库里
2)逐行解读代码:
表达式 (= + - * % / ++ --! 参数...):能够做一些改变的东西
上面代码 alert(a) 在仓库里面找到 var a =undefined ,所以返回undefined;
虽然仓库里面有函数fn1,但是JS里面没有调用,所以根本就不会有结果!
一个实例
<script> alert(a); //弹出funtion 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>
以上,先预解析:找到了 var funciton 参数。。。
a=未定义
a=function a(){alert(2)}
a=未定义
a=function a(){alert(4)}
遇到重名的:只留下一个!
变量和函数重名,只留下函数:a=function a(){alert(2)}
函数和函数重名,留下最后面的函数 a=function a(){alert(4)}
2)逐行解读代码
表达式:可以修改预解析的值!
上面代码执行完成后+一个a() //报错,因为仓库里面什么都没有了 a is not a funciton! a变成了一个数字
<script> var a=1; </script> <script> alert(a); </script>
多个域:自上而下,并且仓库公用的!
作用域链
函数调用:由里到外 局部的域 1)预解析
2)逐行解读
<script> var a=1; function fn1(){ alert(a); //Undefined 局部a; var a=2; // 1 全局a; } fn1(); alert(a) </script>
<script> var a=1; function fn1(){ alert(a); //1 作用域链,找到外面var a=1; a=2; // 局部有能力去改外面的值,变成全局变量var a=2; } fn1(); alert(a) //2 </script>
<script> var a=1; function fn1(a){ //参数本质上就一个局部变量 ,a= undefined alert(a); //Undefined a=2; // 参数 a=2; } fn1(); alert(a); //1 </script>
注意看注释!