本文實例分析了JS作用域閉包、預解釋和this關鍵字。分享給大家供大家參考,具體如下:
var number = 2; var obj = {number : 5, fn1 : ( function() { this.number *= 2; number=number*2; var number=3; return function() { this.number *= 2; number*=3; alert(number); } } )() }; var fn1 = obj.fn1; alert(number); fn1(); obj.fn1(); alert(window.number); alert(obj.number);
【解析】
1. fn1本身後面就有(),所以var fn1 = obj.fn1;時他已經被執行,但是裡面的return function並沒有被執行
2. alert(number);輸出全局的number,本來是2,經過var fn1 = obj.fn1;後,相當於執行了
this.number *= 2; number=number*2; var number=3;
這三句話
注意:任何一個直接執行的匿名方法,他的this指向window
所以this.number *= 2;使得全局變量變成4,即輸出4
而number=number*2;他是去看作用域塊裡的number,var number=3;作用域聲明在先,但是沒有賦值,所以number=number*2;這句話其實沒用
3. 執行到fn1();就是執行fn1裡面的return function,也就是這三句話
this.number *= 2; number*=3; alert(number);
這時候依然是個匿名方法,所以this.number *= 2;使得全局變量變為8,number*=3;去找作用域塊裡的number,外層定義number為3,所以alert(number);就是9,如果是alert(this.number);則指向全局變量,即輸出8
4. obj.fn1();,依然執行fn1裡面的return function,也就是這三句話
this.number *= 2; number*=3; alert(number);
但這時this指向obj,this.number *= 2;使得obj裡的number變為10,number*=3;還是去找作用域塊,由於上面變為9,所以這裡就是27,alert(number);輸出的是作用域塊的number,即27,如果是alert(this.number);則指向obj的number,即輸出10
5. alert(window.number);經過上面幾輪,全局變量變為8(即執行obj.fn1();對全局變量無影響)
6. alert(obj.number);只有這句話obj.fn1();,改變了obj.number,所以輸出10
(function(){ var a=10; fn(); function fn(){ var a=a+10; console.log(a); return a; } console.log(a); console.log(fn()+10); })();
fn函數裡的a先被聲明但是沒有賦值,然後進行運算,他不會去找函數外面的同名變量,因為他已經在裡面被聲明了。一個不是數字的和數字進行運算,輸出NaN
console.log(fn()+10);這句話要輸出兩個值:console.log(fn());和console.log(fn()+10);
結果:
NaN
10
NaN
NaN
如果題目改成
(function(){ var a=10; fn(); function fn(){ a=a+10; console.log(a); return a; } console.log(a); console.log(fn()+10); })();
結果:
20
20
30
40
更多關於JavaScript相關內容感興趣的讀者可查看本站專題:《JavaScript數組操作技巧總結》、《JavaScript排序算法總結》、《JavaScript遍歷算法與技巧總結》、《JavaScript數學運算用法總結》、《JavaScript數據結構與算法技巧總結》、《JavaScript查找算法技巧總結》及《JavaScript錯誤與調試技巧總結》
希望本文所述對大家JavaScript程序設計有所幫助。