1. 程式人生 > >做預解釋題的一點小方法和小技巧

做預解釋題的一點小方法和小技巧

改善 返回值 第一次 都是 做出 cti 條件判斷 false 回調函數


在JavaScript中的函數理解中預解釋是一個比較難懂的話題。原理雖然簡單,寥寥數言,但其內涵卻有深意,精髓難懂。如何在輕松活躍的頭腦中將它學會,現在針對我在學習中的一點小竅門給大家分享一下,希望能給大家一些幫助:


萬事需遵循“原理”——“預解釋”無節操和“this”指向:(可先看例題解析然後結合原理進行學習)

(感謝蕾蕾老師給歸納的預解釋無節操原理:)


如果函數傳參數則先於以下執行,就相當於在函數私有作用域下var了一個變量;根據作用域原理,私有作用域的權重永遠大於父級作用域,當我私有作用域中有某個變量時,而我正好需要他時,私有作用域變量的值就是我所需要的;當私有作用域中沒有時,而我有恰好需要它時,我就會沿著作用域鏈一級級的往上找。此時可得出子級可以用父級的變量,但父級不能訪問子級的作用域,打個簡單的比喻可能不太貼切,子孫能繼承祖宗的財產,但祖宗不能繼承子孫的財產,因為祖宗都沒了,還怎麽繼承。


1. 只對等號左邊帶var的,聲明但不定義
2. 自執行函數不會進行預解釋,只有,執行到他的時候,聲明+定義+調用同步完成
3. 已經聲明過的不會進行重復聲明,但會重新賦值;
4. return下面的語句雖然不會執行,但會進行預解釋;
5. 函數的聲明早於變量的聲明
6. 在條件判斷語句中,無論條件是否成立,都會進行預解釋;
不要在條件判斷語句中寫函數的定義階段;否則,各大瀏覽器對其的兼容性不同
this指向:


1. 當一個元素身上的事件被觸發的時候,會執行一個函數,函數中的this指向當前這個元素;
2. 自執行函數中的this,永遠都是window
3. 回調函數中的this,一般都是window

setInterval(函數名,1000) ary.sort(function(){})
4. 當函數被調用的時候,看前面是否有".""."前面是誰,this就是誰;

原理闡述篇————實例小竅門篇:
1

(function f(){
function f(){ return 1; }
alert (f());
function f(){ return 2; }
})();
解析:此函數為自執行函數,觀察函數,註意類似於function fn(){}這樣的才是聲明函數,像var f=function(){}b=function(){}這樣的都不屬於聲明函數,前者屬於變量的聲明,


只有像聲明函數那樣的在函數才會進行預解釋,此題中兩個為需要聲明的函數為同名函數,所以根據已經聲明過的不會進行重復聲明,但會重新賦值原理得到函數預解釋為 function f(){ return 2; }
此時,當函數執行時


alert (f())的結果為2
2


var a=12;
function show(){
alert(a);
a=15;
}
show();
alert(a);

解析:此題為對作用域鏈的考察,先進行預解釋,特別提示變量只有聲明,函數既有聲明還有定義,預解釋了之後代碼執行時就會自動跳過不執行,但var a=12,這相當於給變量重新賦值,因為任何變量進行預解釋的初始值為

undefined;本題先對變量和函數進行預解釋:var a=undefined;

function show(){
alert(a);
a=15;
}
預解釋完畢後,代碼從上往下的執行,1. a=12; 2. function show(){alert(a);a=15}已經經過預解釋不會執行; 3. show()進行函數的調用,alerta.當前作用域下沒
a,就去父級作用域,a=124.接著執行a=15,任何在函數私有作用域下變量前面不帶var的本身不屬於當前作用域域,而是對全局作用域中全局變量的重新賦值,所
以此時相當於把全局變量中的a直接賦值為15; 5.最後在全局作用域下alert(a),只能訪問自己的變量。所以a=15;

此題答案為 12,15

此題引申:


var a=12;
function show(){
alert(a);
var a=15;
}
show();
alert(a);

此時輸出的結果為undefined12,你猜對了嗎?切記私有作用域中的變量是以var為基準的,當然如果傳參數例外,因為傳參就相當於最先var,此題在show函數執行時,因為


裏面有var,所以肯定有私有變量所以var a,接著alerta),大家應該沒有忘記任何變量的預解釋初始值為undefined,接著執行var a=15,此時相當於重新賦值,這裏不用有疑問,因為代碼
是從上往下執行,接著繼續執行外面全局變量中的alerta)此時值為12,因為函數私有作用域中並沒有改變全局變量的值。

再引申:


var a=12;
function show(a){
alert(a);
var a=15;
}
show(a);
alert(a);
此題結果應為12,12,此題相對於上一題做的改善是對函數進行了傳參數處理,上面提過傳參相當於最先進行var變量處理,所以在show函數執行時,私有變量a的最開始賦值就為12,在執行就相當於重新賦值

事已至此,咱們再引申一下:


var a=12;
function show(a){
alert(a);
a=15;
}
show(a);
alert(a);
此題結果應該為:12,15,此題主要關鍵點為全局變量的從新賦值:

那麽大家肯定就更能做出這道題了:


alert(a);
var a = 12;
function show(a) {
alert(a);
var a = 15;
alert(a);
}
show(a);
alert(a);


此題結果為undefined1215,12

2:接下來我們來討論一下變量和函數的一些關系:


function a() {
var b=10;
alert(b);
};
var a;
a();
解析:此題中變量和函數為同名,根據原理知識我們可以知道,函數的聲明要優先於變量的聲明,所以當同名時以函數優先,所以不難的出此題的答案為10;別急,你以為這麽簡單就完了,來開始做個小修改
引申一下:


function a() {
var b=10;
alert(b);
};
var a=6;
a();
解析:大家猜猜這道題的結果,如果你對上面的原理理解的不錯的話,那麽你應該很容易得出此題會報錯,a is not defined; 確實函數占用了名稱,當接下來執行var a=6,時,大家要註意了,只要變量
有等號就相當於重新賦值,但大家疑問來了,為啥會報錯呢,請註意a的名字已經被函數占用,當你進行var a=6,時此時你又把a賦值給6,此時函數本身就猶如孤魂野鬼,沒有名字,當最後調用啊a()我去哪找函數a,所以必須的必肯定會報錯!!!
3


if("a" in window){
var a=15;
}
function fn() {
alert(a)
}
fn()
解析:此題考查的知識點為在條件判斷語句中,無論條件是否成立,都會進行預解釋,在此題中,大家也應該記住類似於“a” in window 都是正確的,所以起先會進行預解釋 var a, 因為條件成立,進入
條件語句中會進行重新賦值,此時a=15;在函數中alerta,向上級作用域尋找a,結果為15

引申:


if(!"a" in window){
var a=15;
}
function fn() {
alert(a)
}
fn()
解析:加個,條件肯定為false,不進入條件,但會進行預解釋var a,此時a 的值為undefined

接下來將他們綜合起來先來個簡單的


var name=‘haha‘;
var age=500;
name=(function(name,age){
arguments[0]=‘xixi‘;
age=age||this.age;
console.log(name,age);
})(name);
console.log(name,age)
解析:看到此題,來吧先進行預解釋,1.var name;var age;此時有個註意點,name=...;等號後面的函數不會進行預解釋。2.代碼從上到下執行,name=‘haha‘;age=500;3.接下來是個關鍵點name等於一個自執行函數,先看看它有沒有返回值,一個函數執行後若沒有返回值則結果都等於undefined,所以此時全局name=undefined,此時自執行函數執行時,函數經過傳參,就相當於提前var,所以有私有變量,arguments[0]=‘xixi‘;此時就相當於將函數私有作用域中name=xixi;age=age||this.age,自執行函數的this指向為window,"||"為或的意思,有一項成立就行,那麽age=500.第一次console結果應該為xixi,500 4.全局的console我們剛才分析了name富裕沒有返回值的自執行函數時為undefined,所以結果為undefined,500;



今天先更新點簡單的,明天加上內存釋放等問題,通過特殊的小技巧讓你事半功倍,做爽預解釋,不用畫圖也能看出答案。。。

未完,待續....


 

做預解釋題的一點小方法和小技巧