js幾個經典的題目詳解

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]就很容易理解了。
相關文章
相關標籤/搜索