浏览器:
“JS解析器”
1)JS 的预解析 “找一些东西” :var function 参数
a = ...
所有的变量,在正式运行代码之前,都提前赋了一个值:未定义
fn1 = function fn1(){ alert(2); }
所有的函数,在正式运行代码之前,都是整个函数块
遇到重名的:只留一个
变量和函数重名了,就只留下函数
相同的函数名的话, 后面会覆盖前面的函数
2)逐行解读代码:
表达式:= + - * / % ++ -- ! 参数……
表达式可以修改预解析的值!
注意: 函数声明不叫表达式
在逐行解读代码的过程中,如果遇到函数调用,那么js解析器,就又会重复上面两步。
1、预解析,2,、逐行解读代码 函数里面没有的东西(变量等),它会顺着作用域链网上找,去找父类的
3) script标签: 如果一个页面有两块或多块script标签的, js是自上而下去执行的,上面的执行完毕后(预解析、逐行解读代码),才会执行下面的区域,执行上面区域的时候,会把上面都信息保留下来(变量值啊....等)。
4) 即使有对个函数嵌套,那js解析器的执行的步骤还是,那两步先去预解析,再去逐行执行代码,遇到函数调用后再到函数里面,重复的去执行先前那两步...
案例一:
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这个方法了, 只有 a = 3; 3() //这样写必然会报错
案例二:
var a = 1;
function fn1(){
alert(a); // undefined
var a = 2;
}
fn1();
alert(a); // 1
案例三:
var a = 1;
function fn1(){
alert(a); // 1
a = 2;
}
fn1();
alert(a); // 2
案例四:
var a = 1;
function fn1(a){
alert(a); // undefined
a = 2;
}
fn1();
alert(a); // 1
案例五:
var a = 1;
function fn1(a){
alert(a); // 1
a = 2;
}
fn1(a);
alert(a); // 1
原文:http://www.cnblogs.com/zsongs/p/5149688.html