1:预解析:碰到var function 参数会将这些预存到仓库
2:逐行读代码:表达式 =+-*/% 参数
例子1:
alert(a); //function a(){alert(4);} var a = 1;
alert(a);//1functiona(){alert(2);}//函数的声明直接往下读
alert(a);//1var a = 3;
alert(a);//3functiona(){alert(4);}//函数的声明直接往下读
alert(a);//3
alert(typeof a)//number
a();//函数调用 仓库已经不存在任何函数了-->相当于3();//会报错 a is not a function
1:预解析:找一些东西 var function 参数(放入仓库)
01:a = 未定义
a = function a(){alert(2);}
注:一旦出现重名的,会只留一个(和上下文没有关系,变量和函数重名,就只留下函数)
02:a = function a(){alert(2);}
a = 未定义;
踢出未定义
03:a = function a(){alert(2);}
a = function a(){alert(4);}
函数遇到函数根据上下文的关系保留a = function a(){alert(4);}
例子2:
alert(a);//undefinedvar a = 1;
alert(a)//1functionfn1(){alert(2)}
1:预解析:找一些东西 var function 参数(放入仓库)
a = 未定义所有的变量在正式运行代码前都提前赋了一个值:未定义
fn1()=function fn1(){alert(2)}
2:逐行读代码(从仓库读取)
//var a function fn1(){alert(2)}函数声明
//a=1表达式 +-*/%++--! Number()参数; 做一些改变的动作
例子3:
var a = 1;
functionfn1(){
alert(a);//undefinedvar a = 2;
}
fn1();
alert(a);//1
1:预解析:
a = 未定义
fn1 = function fn1(){alert(a);var a = 2;}
2:逐行读代码:
a = 1;
遇到函数声明直接跳
遇到函数调用再次触发预解析:
01:预解析:
碰到var 定义变量 a = 未定义
02:读代码:
优先的从局部范围内查找有没有定义一个a的值
例子4:
var a = 1;
functionfn1(){
alert(a);//1
a = 2;//修改全局的a
}
fn1();
alert(a);//2
1:预解析:
a = 未定义
fn1 = function fn1(){alert(a); a = 2;}
2:逐行读代码:
a = 1;
函数声明直接跳
遇到函数调用再次触发预解析:
01:预解析:没有var function 参数直接读代码
02:读代码:
优先的从局部范围内查找有没有定义一个a的值 如果没有会顺着子级作用域往父级作用域找(作用域链)
例子5:
var a = 1;
functionfn1(a){//function fn1(var a;){
alert(a);//undefined
a = 2;
alert(a);//2
}
fn1();
alert(a);//1
1:预解析:
a = 未定义
fn1 = function fn1(){alert(a); a = 2;alert(a);}
2:逐行读代码:
a = 1;
函数声明直接跳
遇到函数调用再次触发预解析:
01:预解析:
参数本质上就是局部变量var a
a= undefined
02:读代码:
根据就近原则里面有个a = undefined
例子6:
var a = 1;
functionfn1(a){//function fn1(var a = 1){
alert(a);//1
a = 2;
}
fn1(a);//里面的参数来自全局
alert(a);//1
1:预解析:
a = 未定义
fn1 = function fn1(a){alert(a); a = 2;}
2:逐行读代码:
a = 1;
函数声明直接跳
遇到函数调用再次触发预解析:
01:预解析:
参数本质上就是局部变量var a
a= undefined
02:读代码:
从参数开始读
全局上的a = 1赋值给局部变量a;
调用局部函数
01:通过全局变量
var num = 0;
functionfn1(){
num++;
}
functionfn2(){
num--;
}
fn2();
fn1();
fn2();
alert(num)//-1