成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

怪異的JavaScript系列(二)

YacaToy / 1760人閱讀

摘要:函數(shù)不是函數(shù)這是一個(gè)低版本的,,或則。對(duì)應(yīng)的進(jìn)制數(shù)為。因此最安全的方法是調(diào)用的時(shí)候指定進(jìn)制。它會(huì)將字符串形式的整數(shù)轉(zhuǎn)換為,非字符串的,,和也會(huì)被轉(zhuǎn)換。對(duì)于不能轉(zhuǎn)換的值,返回。而瀏覽器主要指系列,其實(shí)已經(jīng)沒有必要支持這個(gè)特性了。

譯者按: JavaScript有很多坑,經(jīng)常一不小心就要寫bug。

原文: What the f*ck JavaScript?

譯者: Fundebug

為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。

JavaScript是一門偉大的語(yǔ)言,它擁有非常簡(jiǎn)潔的語(yǔ)法,龐大的生態(tài)系統(tǒng),以及最重要的:有一個(gè)偉大的社區(qū)支撐著。同時(shí),我們也知道JavaScript是一個(gè)充滿技巧性的語(yǔ)言。有些坑足以讓我們崩潰,也有些奇淫技巧讓我們覺得很有趣。本文的思想源自于Brian Leroux在dotJS2012上的演講“WTFJS” at dotJS 2012。

我收集這些例子的主要目的是將它們整理并清楚理解它們的原理。從中學(xué)到很多以前不懂的知識(shí)是一件很有趣的事情。如果你是初學(xué)者,你可以通過(guò)學(xué)習(xí)這些筆記深入理解JavaScript;如果你是一個(gè)專業(yè)的開發(fā)者,那么可以將這些筆記作為一個(gè)不錯(cuò)的引用資料。不管怎樣,只要讀下去,你就會(huì)學(xué)到新東西的。

函數(shù)不是函數(shù)?
?? 這是一個(gè)低版本的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 … … …

備注:經(jīng)測(cè)試高版本(Node.js, v8.1.1)不會(huì)出現(xiàn)這個(gè)bug。如果你還沒升級(jí)到高版本,不妨試一下看看?

數(shù)組相加

如果我們將兩個(gè)數(shù)組相加,結(jié)果會(huì)怎樣?

[1, 2, 3] + [4, 5, 6]  // -> "1,2,34,5,6"

實(shí)際上是做了拼接操作,我們來(lái)一步一步解釋:

[1, 2, 3] + [4, 5, 6]
// 調(diào)用 toString()
[1, 2, 3].toString() + [4, 5, 6].toString()
// 字符串拼接
"1,2,3" + "4,5,6"
// ->
"1,2,34,5,6"
數(shù)組中分號(hào)的去除

我們創(chuàng)建一個(gè)4個(gè)空元素的數(shù)組。結(jié)果呢,該數(shù)組實(shí)際上只有3個(gè)元素,因?yàn)樽詈笠粋€(gè)分號(hào)被去掉了。

let a = [,,,]
a.length     // -> 3
a.toString() // -> ",,"
末尾分號(hào)(Trailing commas)(又叫做final commas)在添加新元素、參數(shù)或則屬性時(shí)候很有用。如果你想增加一個(gè)新的屬性,并且前一行末尾有使用分號(hào),你可以直接在新的一行添加而不用修改前一行。這可以讓版本控制的diff操作更加清晰,代碼更少出問(wèn)題。-  Trailing commas at MDN
數(shù)組相等匹配非常恐怖

請(qǐng)看:

[] == ""   // -> 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

具體請(qǐng)參考7.2.13 Abstract Equality Comparison

undefined和Number

如果不給Number構(gòu)造函數(shù)傳入任何參數(shù),那么返回0。如果傳入undefined作為參數(shù),會(huì)返回NaN。

Number()          // -> 0
Number(undefined) // -> NaN

根據(jù)規(guī)范:

如果沒有參數(shù)傳入,那么n=0;

否則,n= ToNumber(value);

如果value為undefined,那么ToNumnber(undefined)為NaN。

參考:

20.1.1 The Number Constructor

7.1.3 ToNumber(argument)

JavaScript坑很多,趕緊使用fundebug扶一扶!

parseInt也不是個(gè)好東西

parseInt因?yàn)樗婀值男袨槎雒?/p>

parseInt("f*ck");     // -> NaN
parseInt("f*ck", 16); // -> 15

這是因?yàn)閜arseInt一個(gè)字符一個(gè)字符去分析,知道遇到無(wú)法處理的字符。f對(duì)應(yīng)的16進(jìn)制數(shù)為15。

Infinity可以轉(zhuǎn)換為對(duì)應(yīng)的數(shù)字:

//
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

小心參數(shù)為null的情況:

parseInt(null, 24) // -> 23
首先,null被翻譯為字符串"null"。"n"在24進(jìn)制中對(duì)于23。-- 更多請(qǐng)參考 “parseInt(null, 24) === 23… wait, what?” at StackOverflow。
parseInt("n", 24) // -> 23

不要忘記了8進(jìn)制:

parseInt("06"); // 6
parseInt("08"); // 8 if support ECMAScript 5
parseInt("08"); // 0 if not support ECMAScript 5

如果輸入的字符串以0開始,那么為8進(jìn)制或則10進(jìn)制。到底是哪一個(gè),要看實(shí)現(xiàn)。如果是ECMAScript5,則為10進(jìn)制。但并不是所有瀏覽器都支持。因此最安全的方法是調(diào)用parseInt的時(shí)候指定進(jìn)制。

parseInt總是將輸入轉(zhuǎn)換為字符串。

parseInt({ toString: () => 2, valueOf: () => 1 }) // -> 2
Number({ toString: () => 2, valueOf: () => 1 })   // -> 1
true和false的數(shù)學(xué)運(yùn)算
true + true // -> 2
(true + true) * (true + true) - true // -> 3

我們把true轉(zhuǎn)換為Number來(lái)看看就明白了:

Number(true) // -> 1

一元加號(hào)運(yùn)算會(huì)嘗試將參數(shù)轉(zhuǎn)換為number。它會(huì)將字符串形式的整數(shù)轉(zhuǎn)換為float,非字符串的true,false,和null也會(huì)被轉(zhuǎn)換。對(duì)于不能轉(zhuǎn)換的值,返回NaN。因此,我們有了一個(gè)更加簡(jiǎn)單的轉(zhuǎn)換方法:

+true // -> 1

當(dāng)你使用加法或則乘法的時(shí)候,ToNumber函數(shù)會(huì)被調(diào)用。根據(jù)定義:

如果參數(shù)為true,返回1. 如果參數(shù)為false,返回+0.
這就是為什么我們布爾類型的值(true,false)可以和數(shù)字相加。

參考:

12.5.6 Unary + Operator

12.8.3 The Addition Operator (+)

7.1.3 ToNumber(argument)

JavaScript中可以使用HTML的評(píng)論方式

在JavaScript中,使用

最新活動(dòng)
閱讀需要支付1元查看
<