譯者按: JavaScript有許多坑,常常一不警惕就要寫bug。
為了保證可讀性,本文採納意譯而非直譯。別的,本文版權歸原作者一切,翻譯僅用於進修。
JavaScript是一門巨大的言語,它具有異常簡約的語法,巨大的生態系統,以及最重要的:有一個巨大的社區支撐着。同時,我們也曉得JavaScript是一個充溢技能性的言語。有些坑足以讓我們崩潰,也有些奇淫技能讓我們覺得很風趣。本文的頭腦源自於Brian Leroux在dotJS2012上的演講“WTFJS” at dotJS 2012。
我網絡這些例子的重要目標是將它們整頓並清楚邃曉它們的道理。從中學到許多之前不懂的學問是一件很風趣的事變。假如你是初學者,你能夠經由過程進修這些筆記深切邃曉JavaScript;假如你是一個專業的開發者,那末能夠將這些筆記作為一個不錯的援用材料。不管怎樣,只需讀下去,你就會學到新東西的。
函數不是函數?
⚠️ 這是一個低版本的bug,V8(<=5.5),或則Node.js(<=7)。
// Declare a class which extends null
class Foo extends null {}
// -> [Function: Foo]
new Foo instanceof null
// > TypeError: function is not a function
// > at … … …
備註:經測試高版本(Node.js, v8.1.1)不會湧現這個bug。假如你還沒升級到高版本,無妨試一下看看?
數組相加
假如我們將兩個數組相加,效果會怎樣?
[1, 2, 3] + [4, 5, 6] // -> '1,2,34,5,6'
實際上是做了拼接操縱,我們來一步一步詮釋:
[1, 2, 3] + [4, 5, 6]
// 挪用 toString()
[1, 2, 3].toString() + [4, 5, 6].toString()
// 字符串拼接
'1,2,3' + '4,5,6'
// ->
'1,2,34,5,6'
數組中分號的去除
我們建立一個4個空元素的數組。效果呢,該數組實際上只要3個元素,由於末了一個分號被去掉了。
let a = [,,,]
a.length // -> 3
a.toString() // -> ',,'
末端分號(Trailing commas)(又叫做final commas)在增添新元素、參數或則屬性時刻很有用。假如你想增添一個新的屬性,而且前一行末端有運用分號,你能夠直接在新的一行增添而不必修正前一行。這能夠讓版本掌握的diff操縱越發清楚,代碼更少出問題。-
Trailing commas at MDN
數組相稱婚配異常恐懼
請看:
[] == '' // -> true
[] == 0 // -> true
[''] == '' // -> true
[0] == 0 // -> true
[0] == '' // -> false
[''] == 0 // -> true
[null] == '' // true
[null] == 0 // true
[undefined] == '' // true
[undefined] == 0 // true
[[]] == 0 // true
[[]] == '' // true
[[[[[[]]]]]] == '' // true
[[[[[[]]]]]] == 0 // true
[[[[[[ null ]]]]]] == 0 // true
[[[[[[ null ]]]]]] == '' // true
[[[[[[ undefined ]]]]]] == 0 // true
[[[[[[ undefined ]]]]]] == '' // true
詳細請參考7.2.13 Abstract Equality Comparison
undefined和Number
假如不給Number組織函數傳入任何參數,那末返回0。假如傳入undefined作為參數,會返回NaN。
Number() // -> 0
Number(undefined) // -> NaN
依據範例:
- 假如沒有參數傳入,那末n=0;
- 不然,n= ToNumber(value);
- 假如value為undefined,那末ToNumnber(undefined)為NaN。
參考:
JavaScript坑許多,趕忙運用fundebug扶一扶!
parseInt也不是個好東西
parseInt由於它新鮮的行動而出名:
parseInt('f*ck'); // -> NaN
parseInt('f*ck', 16); // -> 15
這是由於parseInt一個字符一個字符去剖析,曉得碰到沒法處置懲罰的字符。f
對應的16進制數為15。
Infinity
能夠轉換為對應的数字:
//
parseInt('Infinity', 10) // -> NaN
// ...
parseInt('Infinity', 18) // -> NaN...
parseInt('Infinity', 19) // -> 18
// ...
parseInt('Infinity', 23) // -> 18...
parseInt('Infinity', 24) // -> 151176378
// ...
parseInt('Infinity', 29) // -> 385849803
parseInt('Infinity', 30) // -> 13693557269
// ...
parseInt('Infinity', 34) // -> 28872273981
parseInt('Infinity', 35) // -> 1201203301724
parseInt('Infinity', 36) // -> 1461559270678...
parseInt('Infinity', 37) // -> NaN
警惕參數為null的狀況:
parseInt(null, 24) // -> 23
起首,null被翻譯為字符串”null”。”n”在24進制中關於23。– 更多請參考
“parseInt(null, 24) === 23… wait, what?” at StackOverflow。
parseInt('n', 24) // -> 23
不要忘記了8進制:
parseInt('06'); // 6
parseInt('08'); // 8 if support ECMAScript 5
parseInt('08'); // 0 if not support ECMAScript 5
假如輸入的字符串以0最先,那末為8進制或則10進制。究竟是哪個,要看完成。假如是ECMAScript5,則為10進制。但並非一切瀏覽器都支撐。因而最平安的要領是挪用parseInt的時刻指定進制。
parseInt老是將輸入轉換為字符串。
parseInt({ toString: () => 2, valueOf: () => 1 }) // -> 2
Number({ toString: () => 2, valueOf: () => 1 }) // -> 1
true和false的數學運算
true + true // -> 2
(true + true) * (true + true) - true // -> 3
我們把true轉換為Number來看看就邃曉了:
Number(true) // -> 1
一元加號運算會嘗試將參數轉換為number。它會將字符串情勢的整數轉換為float,非字符串的true,false,和null也會被轉換。關於不能轉換的值,返回NaN。因而,我們有了一個越發簡樸的轉換要領:
+true // -> 1
當你運用加法或則乘法的時刻,ToNumber函數會被挪用。依據定義:
假如參數為true,返回1. 假如參數為false,返回+0.
這就是為何我們布爾範例的值(true,false)能夠和数字相加。
參考:
JavaScript中能夠運用HTML的批評體式格局
在JavaScript中,運用<!--
是一個有用的批評體式格局。
// valid comment
<!-- valid comment too
支撐HTML的批評體式格局的目標是許可那些不支撐<script>
標籤的瀏覽器能夠文雅地降級。而瀏覽器重要指Netscape 1.x系列,實在已沒有必要支撐這個特徵了。
Node.js也是基於V8完成,所以在Node.js中也能夠運用。
NaN是Number
NaN的範例是’number’:
typeof NaN // -> 'number'
假如想相識typeof和instanceof怎樣事情,參考:
[]和null是對象
typeof [] // -> 'object'
typeof null // -> 'object'
// 然則
null instanceof Object // false
依據typeof的定義,關於null,作為一個沒有完成[[Call]]
的對象,返回”object”。
你能夠用toString函數來搜檢對象的詳細(Array, Date, Null)範例:
Object.prototype.toString.call([])
// -> '[object Array]'
Object.prototype.toString.call(new Date)
// -> '[object Date]'
Object.prototype.toString.call(null)
// -> '[object Null]'