1. 程式人生 > >幾道容易出錯的JavaScript題目

幾道容易出錯的JavaScript題目

下面這幾道JavaScript題目大多來自於週五的一個小分享。都是很小的題目,但是很容易犯錯。有一些是語言特性使然,有一些則是語言本身沒有設計好而留下的陷阱。結果就是,遇到的人很容易陷進去罵娘,這些東西是略有些反直覺,感興趣的不妨看看,平時我們還是儘量少些這樣似是而非的程式碼。

1.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function Container( properties ) { var objthis = this; for ( var i in properties ) { (function(){ var
t = properties[i]; objthis[ "get" + i ] = function() {return t;}; objthis[ "set" + i ] = function(val) {t = val;}; })(); } } var prop = {Name : "Jim", Age : 13}; var con = new Container(prop); console.log(con.getName()); con.setName("Lucy"); console.log(con.getName()); console.log(prop.Name);

這段程式碼會輸出什麼?前面兩行分別是“Jim”和“Lucy”,這不會有問題;但是第三行應該輸出的是“Jim”,但是有的人會誤認為prop物件已被修改,故輸出“Lucy”。其實在匿名函式中,properties[i]的值已經賦給了臨時變數t,之後閉包對於外部變數的引用完全由t這個媒介來完成,因此prop傳入以後並未發生任何屬性的更改。

2.

1 2 3 4 5 function a (x) { return x * 2; } var a; console.log(a);

這段程式碼中,其實var a並沒有任何影響,輸出的是a(x)這樣的方法簽名。

3.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 c = 999; var c = 888; console.log(this.c); //① function b (x, y, c) { c = 6; arguments[2] = 10; console.log(c); //② console.log(this.c); //③ var c = 6; console.log(c); //④ console.log(this.c); //⑤ } b(1, 2, 3, 4);

這道題是比較變態的。

  • 第①處,this指的是window,在window下,c、this.c、var c在這裡指的是同一個東西,看透這一點就好辦了。列印的是888。
  • 第②處,方法體中,引數c和arguments[2]指的是同一個地址,所以把後者賦為10的時候,列印的是10,不是6。
  • 第③處,this指的是window,列印的是888。
  • 第④處,列印的是6。
  • 第⑤處,列印的是888。

4.

1 2 3 4 5 6 7 8 9 var start = new Date(); setTimeout( function(){ var end = new Date(); console.log(end - start); }, 1000 ); while(new Date() - start < 2000);

JavaScript因為是單執行緒工作的,因此雖然毀掉函式設定了1000毫秒後執行,事實上在1000毫秒的時候根本得不到執行,等待到while迴圈執行完畢後(因此已經是2000毫秒以後了),才去執行,因此輸出應該是一個大於2000的數字。

5.

1 2 3 (function(){ console.log(typeof arguments); })();

很多人會說列印的是array,其實,arguments不是陣列,列印的是object。

6.

1 2 function a(){return a;} console.log(new a() instanceof a);

應該列印的是false,其實原因很簡單,new a()的時候,因為return語句,得到的不是a的例項,而是a本身,a instanceof a當然是false啦。

最後,還有一個小題目是關於Function Invocation Pattern的,我在這篇文章裡有寫到,就不單獨貼出來了。

文章系本人原創,轉載請保持完整性並註明出自《四火的嘮叨》