<script>
/*
今天學(xué)習(xí)了JS的解析與執(zhí)行過程娄涩,感覺好牛逼,記錄下來绢要,以便日后復(fù)習(xí)
*/
//一階段
var a = 5;
function f(n){
alert(a);
}
f();
/*
上面代碼的全局處理過程:
1吏恭、預(yù)處理階段
????a、讀取分析整個源代碼
????b重罪、先掃描函數(shù)聲明樱哼,之后掃描變量(var聲明)
????????b_a哀九、處理函數(shù)聲明時有沖突,會覆蓋
????????b_b唇礁、處理變量聲明時有沖突勾栗,會忽略
????c、將掃描到的函數(shù)和變量保存到一個對象中(全局的保存到window對象中)
????d盏筐、變量的值是undefined围俘,函數(shù)的值則指向該函數(shù)(是一個函數(shù)字符串)
? ? ? ? ? ?形式如下:{a : undefined, f : 'function(){alert(a);var a = 5;}'}
2、運行階段
????在我們剛剛的案例中
????a琢融、將變量a的值從undefined改為5
????b界牡、調(diào)用f(),一遍函數(shù)得到執(zhí)行
上面函數(shù)代碼的處理過程:
????1漾抬、預(yù)處理階段
????????a宿亡、將函數(shù)的參數(shù)添加到一個對象(詞法對象)
????????b、掃描函數(shù)聲明纳令,之后掃描變量(var聲明)
????????d挽荠、將掃描到的函數(shù)和方法添加到詞法對象里面
????????c、變量的值是undefined平绩,函數(shù)的值則指向該函數(shù)(與全局的一樣)
????2圈匆、運行階段
????????與全局的的運行原理一樣
*/
//二階段
var b = 1;
function ff(){
alert(b);
var b = 5;
alert(b);
}
ff();
//結(jié)果彈出為:undefined
/*
原因:
js在預(yù)處理階段時,將函數(shù)ff()和變量b保存到window對象中捏雌,
此時b = undefined跃赚,到了運行階段,b = 1性湿,這時調(diào)用函數(shù)ff()纬傲,
js會先把函數(shù)內(nèi)的變量添加到詞法對象中,此時b = undefined肤频,
再之后alert(b)叹括,因為是在方法內(nèi)部,所以alert(b)會調(diào)用詞法
對象中的b宵荒。然而這時詞法對象中的b = undefined领猾,所以執(zhí)行結(jié)
果彈出的是undefined,當(dāng)alert執(zhí)行完之后b = 5;
*/
//三階段
alert(a);
function a() {
console.log("xx");
}
var a = 5;
function a() {
console.log("yy");
}
//運行結(jié)果:'function a() { console.log("yy"); }'
/*
原因:
我們發(fā)現(xiàn)變量a和兩個方法a()同名了,這時骇扇,js在預(yù)處理的時候
會優(yōu)先將函數(shù)保存到window對象中,然后如果發(fā)現(xiàn)同名的是
變量面粮,這時它會忽略這個變量少孝;如果發(fā)現(xiàn)同名的是函數(shù),那
么后面的會將前面的覆蓋熬苍。所以執(zhí)行alert彈出的會是函數(shù)
*/
/*************************************************************/
alert(b);
var b = 5;
var b = function () {
console.log("xx");
}
//運行結(jié)果:undefined
/*
原因:
我們知道稍走,定義一個方法有多種形式袁翁。像上面這個案例中,
我們的函數(shù)是匿名的婿脸,然后賦值給了一個變量粱胜。但變量終究
是變量,js不會因為它的值比較特別就特殊對待狐树,所以焙压,在
js在預(yù)處理的時候,先將第一個變量b保存到window中抑钟,此時
變量b=undefined,然后第二個變量b覆蓋了第一個變量涯曲,此時
的變量b依然還是等于undefined,所以在程序運行的時候彈出
值會等于undefined在塔。
*/
function c(num1){
alert(num1);
}
c(2);
//運行結(jié)果:2
function d(num2){
alert(num2);
var num2 = 5;
}
d(2);
//運行結(jié)果:2
/*
原因:
在運行前幻件,我就猜想彈出的這個應(yīng)該是一個undefined的
可沒想到卻是2,這使我百思不得其解蛔溃。于是請教老師得
出答案绰沥。
在js預(yù)處理的時候讀取到了這個函數(shù)有一個參數(shù),于是就
直接將這個參數(shù)放到了詞法對象中贺待,這是這個參數(shù)的值是
undefined徽曲,之后它繼續(xù)向下掃描,發(fā)現(xiàn)有一個變量定義狠持,
但我們卻發(fā)現(xiàn)這變量與參數(shù)同名疟位,這個時候js會怎么做?
這時按照之前所學(xué)的喘垂,這個變量會被加到詞法對象中甜刻,而
事實上也的確是加了,不過卻給它打上了一個標簽正勒,用來
標識這個變量是一個參數(shù)得院,這時這個變量的值也是undef-
ined。當(dāng)程序真正運行的時候章贞,我們把參數(shù)傳過去祥绞,這個
參數(shù)就會賦值的到這個參數(shù)中,然后彈出結(jié)果鸭限,然后再賦
值為5蜕径。
接下來還有幾個問題
1.看下面代碼
funciton f(num){
alert(num);
funciton num(){
}
}
f(6);
返回結(jié)果為:'funciton num(){}'
像出現(xiàn)上面這個情況的時候,js也還是一樣在預(yù)處理的時
候败京,將參數(shù)放到詞法對象中兜喻,然后發(fā)現(xiàn)里面有一個同名的
函數(shù),這時js就會把這個函數(shù)放到詞法對象中赡麦,并覆蓋之
前的參數(shù)朴皆,而它的值指向的就是這個函數(shù)帕识。當(dāng)我們程序真
正運行時,我們把參數(shù)傳過去遂铡,js在這里并不會把6這個參
數(shù)值賦值給這個形參肮疗。
(哎呀,一不小心忘了扒接,明天再去問問老師伪货,這里先不嗶嗶,日后補上V樵觥)
*/
</script>
理解上可能會有些錯誤超歌,不喜勿噴!
覺得還好蒂教,記得點個贊哦巍举!