1、做用域、運算符(逗號運算、賦值運算)瀏覽器
1 var out = 25, 2 inner = { 3 out: 20, 4 func: function () { 5 var out = 30; 6 return this.out; 7 } 8 }; 9 console.log((inner.func, inner.func)()); 10 console.log(inner.func()); 11 console.log((inner.func)()); 12 console.log((inner.func = inner.func)());
1 25,20,20,25 2 3 代碼解析:這道題的考點分兩個 4 1.做用域 5 2.運算符(賦值預算,逗號運算) 6 7 先看第一個輸出:25,由於(inner.func, inner.func)是進行逗號運算符,逗號運算符就是 運算前面的, 8 返回最後一個,舉個栗子 9 10 var i=0,j=1,k=2; 11 console.log((i++,j++,k))//返回的是k的值 2 ,若是寫成k++的話 這裏返回的就是 3 12 console.log(i);//1 13 console.log(j);//2 14 console.log(k);//2 15 16 回到原題(inner.func, inner.func)就是返回inner.func而inner.func只是一個匿名函數 17 function () { 18 var out = 30; 19 return this.out; 20 } 21 並且這個匿名函數是屬於window的 22 則變成了 23 (function () { 24 var out = 30; 25 return this.out; 26 })() 27 此刻的this--》window 28 29 因此out 是25 30 31 第二和第三個console.log的做用域都是 foo,也就是他們執行的實際上是 32 foo.func(); 33 foo做用域中是有out變量的,因此結果是20 34 35 第四個console.log 36 考查的是一個等號運算inner.func = inner.func 其實返回的是運算的結果, 37 舉個栗子 38 var a=2,b=3; 39 console.log(a=b)//輸出的是3 40 因此inner.func = inner.func 返回的也是一個匿名函數 41 function () { 42 var out = 30; 43 return this.out; 44 } 45 46 此刻 道理就和第一個console.log同樣了 輸出的結果是 25
2、變量聲明提早函數
1 if (!("a" in window)) { 2 var a = 1; 3 } 4 alert(a);
1 代碼解析:若是window不包含屬性a,就聲明一個變量a,而後賦值爲1。 2 3 你可能認爲alert出來的結果是1,而後實際結果是「undefined」。要了解爲何, 4 須要知道JavaScript裏的3個概念。 5 6 首先,全部的全局變量都是window的屬性,語句 var a = 1;等價於window.a = 1; 7 8 你能夠用以下方式來檢測全局變量是否聲明:"變量名稱" in window 9 第二,全部的變量聲明都在範圍做用域的頂部,看一下類似的例子: 10 11 alert("b" in window); 12 var b; 13 14 此時,儘管聲明是在alert以後,alert彈出的依然是true,這是由於JavaScript引擎 15 首先會掃墓全部的變量聲明,而後將這些變量聲明移動到頂部,最終的代碼效果是這樣的: 16 17 var a; 18 alert("a" in window); 19 這樣看起來就很容易解釋爲何alert結果是true了。 20 21 第三,你須要理解該題目的意思是,變量聲明被提早了, 22 但變量賦值沒有,由於這行代碼包括了變量聲明和變量賦值。 23 24 你能夠將語句拆分爲以下代碼: 25 26 var a; //聲明 27 a = 1; //初始化賦值 28 當變量聲明和賦值在一塊兒用的時候,JavaScript引擎會自動將它分爲兩部以便將變量聲明提早, 29 不將賦值的步驟提早是由於他有可能影響 代碼執行出不可預期的結果。 30 31 因此,知道了這些概念之後,從新回頭看一下題目的代碼,其實就等價於: 32 33 var a; 34 if (!("a" in window)) { 35 a = 1; 36 } 37 alert(a); 38 這樣,題目的意思就很是清楚了:首先聲明a,而後判斷a是否在存在,若是不存在就賦值爲1, 39 很明顯a永遠在window裏存在,這個賦值語 句永遠不會執行,因此結果是undefined。 40 41 提早這個詞語顯得有點迷惑了,你能夠理解爲:預編譯。
3、函數聲明與函數表達式this
1 var a = 1; 2 3 var b = function a(x) { 4 x && a(--x); 5 }; 6 7 alert(a);
1 這個題目看起來比實際複雜,alert的結果是1;這裏依然有3個重要的概念須要咱們知道。 2 3 首先,在題目1裏咱們知道了變量聲明在進入執行上下文就完成了;第二個概念就是函數聲明也是提早的, 4 全部的函數聲明都在執行代碼以前都已經完成了聲明,和變 5 6 量聲明同樣。澄清一下,函數聲明是以下這樣的代碼: 7 8 function functionName(arg1, arg2){ 9 //函數體 10 } 11 以下不是函數,而是函數表達式,至關於變量賦值: 12 13 var functionName = function(arg1, arg2){ 14 //函數體 15 }; 16 澄清一下,函數表達式沒有提早,就至關於平時的變量賦值。 17 18 第三須要知道的是,函數聲明會覆蓋變量聲明,但不會覆蓋變量賦值,爲了解釋這個,咱們來看一個例子: 19 20 function value(){ 21 return 1; 22 } 23 var value; 24 alert(typeof value); //"function" 25 儘快變量聲明在下面定義,可是變量value依然是function,也就是說這種狀況下, 26 函數聲明的優先級高於變量聲明的優先級,但若是該 變量value賦值了,那結果就徹底不同了: 27 28 function value(){ 29 return 1; 30 } 31 var value = 1; 32 alert(typeof value); //"number" 33 該value賦值之後,變量賦值初始化就覆蓋了函數聲明。 34 35 從新回到題目,這個函數實際上是一個有名函數表達式,函數表達式不像函數聲明同樣能夠覆蓋變量聲明, 36 但你能夠注意到,變量b是包含了該函數表達式,而該函數表達式的名字是a;不一樣的瀏覽器對a這個名 37 詞處理有點不同,在IE裏,會將a認爲函數聲明,因此它被變量初始 化覆蓋了,就是說若是調用a(–x)的 38 話就會出錯,而其它瀏覽器在容許在函數內部調用a(–x),由於這時候a在函數外面依然是數字。 39 基本上,IE裏調用b(2)的時候會出錯,但其它瀏覽器則返回undefined。 40 41 理解上述內容以後,該題目換成一個更準確和更容易理解的代碼應該像這樣: 42 43 var a = 1, 44 b = function(x) { 45 x && b(--x); 46 }; 47 alert(a); 48 這樣的話,就很清晰地知道爲何alert的老是1了。
4、函數聲明與變量聲明spa
1 function a(x) { 2 return x * 2; 3 } 4 var a; 5 alert(a);
這個題目比較簡單:即函數聲明和變量聲明的關係和影響,遇到同名的函數聲明,不會從新定義
5、argumentscode
1 function b(x, y, a) { 2 arguments[2] = 10; 3 alert(a); 4 } 5 b(1, 2, 3);
1 關於這個題目,ECMAsCRIPT 262-3的規範有解釋的。 2 3 活動對象是在進入函數上下文時刻被建立的,它經過函數的arguments屬性初始化。 4 arguments屬性的值是Arguments對象. 5 關於 Arguments對象的具體定義,看這裏:ECMAScript arguments 對象
6、call對象
1 function a() { 2 alert(this); 3 } 4 a.call(null);
1 這個題目能夠說是最簡單的,也是最詭異的!關於這個題目,咱們先來了解2個概念。 2 3 這個問題主要考察 Javascript 的 this 關鍵字,具體看這裏: 4 5 關於Javascript語言中this關鍵字的用法 6 7 關於 a.call(null); 根據ECMAScript262規範規定:若是第一個參數傳入的對象調用者是null 8 或者undefined的話,call方法將把全局對象(也就是window)做爲this的值。因此, 9 無論你何時傳入null,其this都是全局對象window,因此該題目能夠理解成以下代碼: 10 function a() { 11 alert(this); 12 } 13 a.call(window); 14 因此彈出的結果是[object Window]就很容易理解了。