a();functiona(){console.log("a")}
先調用再聲明,在沒有預編譯的情況下,不能正常輸出,但是有了預編譯就可以正常輸出,這就是函數整體提升;
定義一個變量 var a = "1233" 這個過程叫做變量的聲明 和 賦值
console.log(a);//undefinedvar a ="1233"
變量 聲明提升,但是賦值未被提升
low點
函數聲明整體提升,變量 的聲明提升 上面說的這兩個點不能解釋下面的代碼
console.log(a);var a ="aaaa";functiona(a){var a =5;}
手動懵逼why???
真·預編譯?前奏 暗示全局變量 imply global
1.任何變量未經聲明就賦值,這個變量就為全局對象(window)所擁有;
----------------------------------------------------------------------------------------------------
2.全局上聲明的任何變量,即使聲明了也歸window 所有;window就是全局的域.
a =1;var b =2;functionddd(){var a = b =12;//賦值是從右向左,,雖然是在函數局部作用域內,12先賦值給了b,b并沒聲明所以b是屬于window的,a是局部的,然后b在賦值給 a}ddd()
AO{a:functiona(){}, // 把形參覆蓋了 注意:**function a(){} 是函數聲明 只有它能提升; var b = function(){}這種是表達式**b:undefined,}
到此AO 對象創建完了 然后馬上執行函數了 電腦從 AO 對象里面 拿東西
所以第一次打印的是function a(){},
a 被賦值123,第二次打印的是123,
然后因為function a(){}已經被提升上去,所以不用看,第三次打印也是123,
第四次打印的function ({被提升,所以最后一次打印是function(){}} 輸出
// }functiontest(a,b){console.log(a);//function a(){};console.log(b);//undefinedvar b =234;console.log(b)//234a =123;console.log(a);//123functiona(){};var a ;b =234;varb=function(){};console.log(a);//123console.log(b);//function(){};}test(1)1.AO:{//過程}2.AO:{a:undefined;b:undefined;}3.AO:{a:1;b:undefined;}4.AO:{a:functiona(){};b:undefined;}
所以第一次輸出的a是 function a(){};b 是undefined
b=234AO:{a:functiona(){};b:234;}下個b輸出就是234a =123AO:{a:123;b:234;}下個a輸出就是123
===中間的聲明對AO對象不產生影響所以輸出不變
varb=function(){};AO:{a:123;b:function(){};}
GO 對象 global object 全局的執行上下文 === window 其實差不多
console.log(a)// 輸出的 function a(){}var a =123;functiona(){}
console.log(a)//1231.GO{}2.GO{a:undefined}3.GO{a:functiona(){}}4.GO{a:123}
GO AO 一起的
console.log(test);// 這個 輸出的是 function test(){},完了之后,就該調用函數了functiontest(test){console.log(test);// function test(){} 這個是自己的testvar test =123;console.log(test);//123functiontest(){}}test(1);var test =123;
理解了預編譯就很簡單
【注】局部輸出或者使用一個變量,或者方法,假如說內外部都有,優先使用內部的(局部的),局部沒有才去全局找
這一點來個超級無敵簡單的例子:
var global =100;functionfn(){console.log(global)// 100;}fn()
很簡單輸出的 100過程 先來個全局 GO 對象 從上到下
GO{global:100,fn:function(){...},}然后執行 fn 來個局部的 AOAO{// 什么都沒有,么有變量和形參聲明,只能去全局GO里面找global 就輸出; 100}
global =100;functionfn(){console.log(global);//undefinedglobal =200;console.log(global);//200var global =300;console.log(global)//300}fn()var global;functiontest(){console.log(b);//undefinedif(a){//a == undefined ==>falsevar b =100;//跳過賦值}console.log(b)undefinedc =234;console.log(c)//234}var a ;test();
a =10;
console.log(c)// GO{// a:undefined;// test:function(){...}// }// AO{// b:undefined, 預編譯,可以跳過循環,循環語句里的變量聲明已經寫入了內存,所以輸出是undefined// 變量c在函數內部沒有聲明,就被全局接受,【參考以上知識點】//}