1:預處理階段
當輸入如下代碼時候
var a = 1;
function crli(){
alert(a);
}
crli()//1
結果爲 1
當改變下面代碼時候
var a = 1;
function crli(){
alert(a);
var a = 5;
}
crli()//undefined
結果爲 undefined
這是爲什麼呢?
js解析與執行過程一共有2個階段,一個預處理階段,一個是執行階段(可以看成全局預處理階段和執行階段,以及函數預處理階段和執行階段)
當js解析代碼時候,會先創建一個lexical environme這麼一個對象,然後掃描js代碼兩個部分:
一個是用聲明方式創建的函數,
另一個是用var 定義的變量,
然後把函數和變量的名字加到lexical environme中,比方說
1 . 全局狀態
lexical environme(**全局的環境對象===window**)
{
a:undefined
crli:對函數的一個引用
}
var a =5;
b = 1;
function crli(){
}
如果非函數聲明、非var方式聲明的變量,則預處理階段不會將函數和變量的名字加到lexical environme中
例子1:
a();//aa
b();//b is not a function
function a() {
console.log("aa");
}
var b = function b(){
console.log("bb");
}
lexical environme
{
a:對函數的一個引用
b:undefined
}
例子2:
console.log(a);//undefined
console.log(b);//b is not defined
var a = 1;
b = 2;
lexical environme
{
a:undefined
}
當遇到函數聲明有衝突時候後者會覆蓋前者,
變量聲明有衝突時候,會忽略
alert(f);//function f(){console.log("s");}
function f(){
console.log("s");
}
var f = 5;
window
{
f:指向函數
}
alert(f);//function f(){console.log("q");}
function f(){
console.log("s");
}
var f = 5;
function f(){
console.log("q");
}
window
{
f:指向函數
}
2 . 函數狀態
function f(a,b){
alert(a);
alert(b);
var b = 100;
function a(){
}
}
f(1,2)//function a(){}
//2
當遇到函數聲明有衝突時候後者會覆蓋前者,
變量聲明有衝突時候,會忽略
lexical environme lexical environme
{ {
a:1 a:指向函數
b:2 ==> b:2
arguments: arguments:
} }
此時解釋
var a = 1;
function crli(){
alert(a);
var a = 5;
}
crli()//undefined
window
{
a : 1
crli:指向函數
}
lexical environme
{
a:undefined
}
函數預處理
執行時,alert(a) 所以是undefind