大家可以測一測自己在這方面知識掌握的程度。
在題後有我參考原博主文章和評論的題目解析,大家競相拍磚。
The quiz:
1:
1 && 3
2:
1 && "foo" || 0
3:
1 || "foo" && 0
4:
(1,2,3)
5:
x = {shift:[].shift};
x.shift(); 3: x.length;
6:
{foo:1}[0]
7:
[true, false][+true, +false]
8:
++'52'.split('')[0]
9:
a: b: c: d: e: f: g: 1, 2, 3, 4, 5;
10:
{a: 1, b: 2}[["b"]]
1
"b" + 45
12:
{a:{b:2}}
13:
(function(){}())
14:
[1,2,3,4,5][0..toString.length]
15:
({} + 'b' > {} + 'a')
16:
Number.prototype.x = function(){ return this === 123; };
(123).x();
17:
Array(2).join()
18:
vars: var vars = vars;
19:
{ foo = 123 }
20:
x = 1; (function(){return x; var x = 2;}())
2
delete [].length;
22:
RegExp.prototype.toString = function() {return this.source};
/3/-/2/;
23:
{break;4;}
24:
'foo' == new function(){ return String('foo'); };
25:
'foo'.split('') + []
解析:
1: #1. //3 : 1為true,進而&&運算繼續執行右邊的表達式,結果為3
2: #2. //"foo" : 邏輯運算符,和上面的一樣,當運算至"foo"時,表達式已經成功,不再執行||右邊的表達式
3: #3. //1 : 1轉換為bool為true,直接返回,不再往下執行
4: #4. //3 : 總返回最後一個值
5: #5. //0 : 當x執行過shift()方法後,x就會擁有length屬性,並且返回的值就是0
6: #6. //[0] : 兩個表達式,返回最後一個表達式的結果
7: #7. //true : 對bool+運算,結果是1或者0於是[true,false][1,0],而這種式子總是取最後一個,[true,false][0]
8: #8. //6 : .運算符優先級大於++運算符,'52'.split('')->['5','2'];取[0]得5;++得6
9: #9. //5 : 忽略掉前面所有的:x 得到:a:1,2,3,4,5 結果:5
10: #10. //SyntaxError。也許你會驚訝,這不是json格式的數據麼,腫麼會報錯?我剛開始也很詫異,實際上這裡不是javascript object,而是塊級結構的語句執行,因為沒有賦值語句。而作為普通語句執行的時候,{a:1;b:2}這樣才對。或者a={a:1,b:2}
11: #11. //"b45" : 字符串與數字加法運算,總是返回字符串
12: #12. //2 : 只不過是兩個語句塊而已,跟第9題實際上是一種情況a:b:2,返回2
13: #13. //undefined : 匿名空函數自執行,由於沒有顯示return語句,自動返回undefined。
14: #14. //2 : 這個很有意思。分兩部分來說,先說0..toString。如果在一個整數後面加".",那麼javascript會認為這是浮點數的點,而不是屬性調用的點,如果在浮點數後面加點,那麼javascript就會認為是屬性調用,因為javascript無法區分此時用戶到底是想進行。於是0..就變成了調用屬性,(這是偶的猜測)這時會把0.轉換成對象,調用其toString函數。倘若直接0.toString是會出現語法錯誤的。你可以測試一下1.1.toString;.0.toString等,都是可以調用的。再說0..toString.length的結果:1,為啥子是1捏,調用函數的length屬性返回的結果是函數的形參個數,javascript默認number.toString函數的形參個數為1。所以,[1,2,3,4,5][1]結果是2。
15: #15. //true : {}+"b" 對象和字符串相加 –> "[object Object]b",之後再進行邏輯比較,"b" > "a"。請不要直接測試{}+"b"這樣你會
得到NaN,為什麼呢,如果這樣的話就是先執行{}這個語句塊,再執行 +"b" 結果自然是NaN。
16: #16. //false 嚴格比較,左邊對象,右邊數字,類型不匹配。
17: #17. //'','' : 數組使用join後轉換為字符串,但是是空數組,所以得到上述結果。
18: #18. //undefined : 都是鹹魚,再怎麼翻身,還是鹹魚。都是undefined,最後當然還是undefined。
19: #19. //123 : 塊語句執行。跟對象神馬的有半點兒毛線關系。
20: #20. //undefined : 據說javascript每引入一個塊作用域都會掃描塊作用域中的"var",並且將有var 生命的變量值設置為undefined,而不管之前是否有過之類的聲明,包括函數體外。
21: #21. //false : 刪毛啊,這能刪麼?【delete only returns false when a property can not be deleted.】
參考:http://perfectionkills.com/understanding-delete/ 文中說的很清楚,內置函數的某些屬性是不能被刪除的,類似於arguments,
length,函數的局部變量(function(){ var a = 1; return delete a })()等。
22: #22. //1 : 先修改正則表達式的原型鏈上的toString函數,返回當前正則實例對象的文本形式。然後就是字符串相減了,這時候會自動轉換為number進行運算。 23: #23. // SyntaxError : break語句只能放在循環和switch分支語句中 24: #24. //false : 借用Damian Wielgosik非常經典的解釋(new function(){ return String('foo'); }).toString() != 'foo'
25: #25. //"f,o,o" : 字符串轉換成數組之後和數組相加再轉換成字符串,可以找兩個數組相加試試,借用Damian Wielgosik的解釋
Just consider e.g. [1, 2] + [3, 4] and see how arrays are casted to string.