一:浏览器读取页面到显示页面做的两件事
1:js预解析
打开浏览器以后,js会去找一些东西,比如:var function 。。。 也就是变量和函数
1)var a= 1;这时,js 会解析var a=未定义
所有的变量,在正式运行代码之前,都提前赋了一个值:未定义。
2)function fun1(){alert(111)}
所有的函数,在正式运行代码之前,都是整个函数代码块。
2:逐行解析代码
表达式:+ - * % ++ -- Number
alert(a)
var a = 1;
alert(a)
这时候,首先会显示undefiend ,是因为代码逐行解析,到alert的时候,查询变量a ,有定义,所以给赋了个初始值,然后再继续往下读。会弹出1,那是因为表达式可以修改预解析的值,把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)
js预解析的工作过程
1:预解析,找一些东西,比如:var function 。。。
首先找到,var a=1; 变量会预解析为 a = undefiend ;
接着找到,function a() { alert(2) },这个函数a和变量a重名,这种情况会只留一个,会把函数留
下。 所以解析为 a = function a() { alert(2) };
再往下找到,var a = 3;变量会预解析为 a = undefiend ;当变量a和上面的方法a进行pk,方法a就会
被踢出,所以解析为 a = function a() { alert(2) };
最后找到, function a(){ alert(4) };当两个函数一起的时候,会遵循上下优先级的原则,所以把a
= function a() { alert(2) };踢出,所以解析为 a = function a(){ alert(4) };
最后到浏览器仓库里面只剩下 a = function a(){ alert(4) }
js逐行执行代码过程的工作过程
1:js每次读取都会去找仓库里面的东西。上面js预解析到最后,仓库里面a被赋值为 a = function a(){ alert(4) };所以,
第一次执行alert(a) 会弹出来函数 function a(){ alert(4) };
2:接着往下走var a=1;把a赋值为1。通过表达式 " = "可以修改预解析a的值,所以,
第二次执行alert(a) 会弹出来函数 1;
3:接着往下走 function a() { alert(2) };只是单纯的声明了一个函数,没有进行赋值,alert(a) 调用的是一个变量,而不是函数,此时仓库里var a = 1;所以,
第三次执行alert(a) 会弹出来函数 1;
4:接着往下走var a = 3;把a赋值为3。通过表达式 " = "可以修改预解析a的值,所以,
第四次执行alert(a) 会弹出来函数 3;
5:接着往下走 function a() { alert(4) };也只是单纯的声明了一个函数,没有进行赋值,alert(a) 调用的是一个变量,而不是函数,所以什么也没有发生,所以,
第五次什么也不弹出,继续往下执行;
6:接着往下走alert(a) ,上面第四次执行的时候给a赋值了3,也就是var a= 3,第五次是个函数,没有执行,多以,
第六次执行alert(a) 会弹出来函数 3;
三 带有局部域浏览器预解析和逐行执行代码过程
var a= 1;
function funa() { alert(a) var a =2; }
funa();
alert(a);
js预解析的工作过程
1 :找到变量 var a= 。。。;
2:找到函数 function funa() { alert(a) var a =2; }
js逐行执行代码过程的工作过程
var a=1;把a赋值为1。a为全局变量 —>
接着往下走是一个函数 ,不解析 —>
接着往下走是funa(),遇到了函数调用,实际上就是让函数里面的东西开始执行。这个时候函数是一个局部的域,所以这时候又会发生域解析 var a =。。。; 然后逐行执行代码 —>
接着执行funa() 里面的alert(a) 此时的a是局部变量a,而不是外面的全局变量a,所以弹出undefiend —>
接着执行 var a =2; 给局部变量赋值为2,跳出函数 —>
最后执行 una()函数下面的 alert(a); 这个时候的a是全局的变量,而第一行var a=1 ,所以弹出 1;
四 带有作用域链的浏览器预解析和逐行执行代码过程
var a= 1;
function funa() { alert(a) a =2; }
funa();
alert(a);
js预解析的工作过程
1 :找到变量 var a= 。。。;
2:找到函数 function funa() { alert(a) a =2; }
js逐行执行代码过程的工作过程
var a=1;把a赋值为1。a为全局变量 —>
接着往下走是一个函数 ,不解析 —>
接着往下走是funa(),遇到了函数调用,实际上就是让函数里面的东西开始执行。这个时候函数是一个局部的域,所以这时候又会发生域解析 ,然而里面又没有变量也没有函数; 这个时候,js会逐行执行代码 —>
接着执行funa() 里面的alert(a),而这个函数里面没有变量a, 此时js会跳出该作用域,去父级作用域找,var a=1;把a赋值为1。所以弹出1—>
接着执行 a =2; 这时候a是全局变量,给全局变量赋值为2,跳出函数 —>
最后执行 funa()函数下面的 alert(a); 这个时候的a是全局的变量,而funa()函数里面a=2了,所以弹出2;
五:带有参数的浏览器预解析和逐行执行代码过程
1:var a= 1;
function funa(a) //这里的a => var a=... 然而funa()没有传参 ,所以alert 是 undefiend
{
alert(a) //undefiend (当a有参数传进来的是 函数里面的a是局部变量,虽然值为1,但不是全局
变量)
a =2;}
funa();
alert(a); // 1
2:var a= 1;
function funa(a) //这里的a => var a=... 然而funa()有传参var a= 1;,所以alert 是 1
{alert(a) // 1 (当a有参数传进来的是 函数里面的a是局部变量,虽然值为1,但不是全局变量)
a =2; } //这时候给a赋值跟全局变量没有关系
funa(a);
alert(a); //1