當(dāng)前位置:
首頁(yè) >
前端技术
> javascript
>内容正文
javascript
怪异的JavaScript系列(三)
生活随笔
收集整理的這篇文章主要介紹了
怪异的JavaScript系列(三)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(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ǔ)言。有些坑足以讓我們崩潰,也有些奇淫技巧讓我們覺(jué)得很有趣。本文的思想源自于Brian Leroux在dotJS2012上的演講“WTFJS” at dotJS 2012。
我收集這些例子的主要目的是將它們整理并清楚理解它們的原理。從中學(xué)到很多以前不懂的知識(shí)是一件很有趣的事情。如果你是初學(xué)者,你可以通過(guò)學(xué)習(xí)這些筆記深入理解JavaScript;如果你是一個(gè)專業(yè)的開(kāi)發(fā)者,那么可以將這些筆記作為一個(gè)不錯(cuò)的引用資料。不管怎樣,只要讀下去,你就會(huì)學(xué)到新東西的。
## return 下面的函數(shù)返回的結(jié)果竟然不是對(duì)象`{b:10}`: (function () {return{b : 10} })() // -> undefined 不過(guò),如果稍微改寫一下,就不一樣了: (function () {return {b : 10} })() // -> { b: 10 } 這主要是因?yàn)橛幸粋€(gè)**自動(dòng)行尾加分號(hào)**的機(jī)制在作怪,會(huì)自動(dòng)在很多新行的行尾添加分號(hào)。在第一個(gè)例子中,實(shí)際上是在return后面添加了分號(hào)。 (function () {return ;{b : 10} })() // -> undefined JavaScript坑很多,趕緊使用[fundebug](https://www.fundebug.com)扶一扶! ## 0.1+0.2=? 一個(gè)眾所周知的笑話就是0.1加上0.2竟然不等于0.3。 0.1 + 0.2 // -> 0.30000000000000004 (0.1 + 0.2) === 0.3 // -> false 在StackOverflow上有關(guān)提到這樣的問(wèn)題“[浮點(diǎn)數(shù)加法運(yùn)算壞了(Is floating point math broken?)](https://stackoverflow.com/questions/588004/is-floating-point-math-broken)”: > 你的程序中0.2和0.3會(huì)在底層用相近的數(shù)據(jù)表達(dá)。double類型數(shù)據(jù)中離0.2最近的數(shù)要比0.2大一點(diǎn)點(diǎn)。離0.3最近的double類型數(shù)據(jù)又剛好比0.3小一點(diǎn)點(diǎn)。所以,結(jié)果就是0.1+0.2的結(jié)果比0.3大。 這個(gè)問(wèn)題非常出名,以至于有一個(gè)專門的網(wǎng)站[0.30000000000000004.com](http://0.30000000000000004.com/)。在所有使用浮點(diǎn)計(jì)算的語(yǔ)言中都有這個(gè)問(wèn)題,不止JavaScript。 ## 神奇的加法操作 999999999999999 // -> 999999999999999 9999999999999999 // -> 1000000000000000010000000000000000 // -> 10000000000000000 10000000000000000 + 1 // -> 10000000000000000 10000000000000000 + 1.1 // -> 10000000000000002 這個(gè)是依據(jù)IEEE 754-2008標(biāo)準(zhǔn)確定的二進(jìn)制浮點(diǎn)運(yùn)算。當(dāng)數(shù)值大到這個(gè)程度,它會(huì)取整到最近的偶數(shù)。參考: - [6.1.6 The Number Type](https://www.ecma-international.org/ecma-262/#sec-ecmascript-language-types-number-type) - [IEEE 754 on Wikipedia](https://en.wikipedia.org/wiki/IEEE_754) ## 為Number自定義 你可以為`Number`和`String`添加自定義函數(shù): Number.prototype.isOne = function () {return Number(this) === 1 }1.0.isOne() // -> true 1..isOne() // -> true 2.0.isOne() // -> false (7).isOne() // -> false 你可以想操縱其它對(duì)象一樣去擴(kuò)展Number對(duì)象。不過(guò),如果定義的函數(shù)不在它本身的定義規(guī)范(Specification)中,那么不建議這么做。這里是一個(gè)參考列表: - [20.1 Number Objects](https://www.ecma-international.org/ecma-262/#sec-number-objects) ## 3個(gè)number比較 1 < 2 < 3 // -> true 3 > 2 > 1 // -> false 我們來(lái)看看具體的執(zhí)行過(guò)程就明白了: 1 < 2 < 3 // 1 < 2 -> true true < 3 // true -> 1 1 < 3 // -> true3 > 2 > 1 // 3 > 2 -> true true > 1 // true -> 1 1 > 1 // -> false ## 有趣的數(shù)學(xué) 3 - 1 // -> 23 + 1 // -> 4 '3' - 1 // -> 2 '3' + 1 // -> '31''' + '' // -> '' [] + [] // -> '' {} + [] // -> 0 [] + {} // -> '[object Object]' {} + {} // -> '[object Object][object Object]''222' - -'111' // -> 333[4] * [4] // -> 16 [] * [] // -> 0 [4, 4] * [4, 4] // NaN 到底是為什么呢? 下面有一個(gè)表供快速參考: Number + Number -> addition Boolean + Number -> addition Boolean + Boolean -> addition Number + String -> concatenation String + Boolean -> concatenation String + String -> concatenation 那么其他例子呢?對(duì)于`[]`和`{}`,toPrimitive和toString方法會(huì)在加法操作前被隱式地調(diào)用。 - [12.8.3 The Addition Operator (+)](https://www.ecma-international.org/ecma-262/#sec-addition-operator-plus) - [7.1.1 ToPrimitive(input [,PreferredType])](https://www.ecma-international.org/ecma-262/#sec-toprimitive) - [7.1.12 ToString(argument)](https://www.ecma-international.org/ecma-262/#sec-tostring) ## 正則也可以做加法? // Patch a toString method RegExp.prototype.toString = function() {return this.source }/7/ - /5/ // -> 2 參考: [21.2.5.10 get RegExp.prototype.source](https://www.ecma-international.org/ecma-262/#sec-get-regexp.prototype.source) ## 箭頭函數(shù) let f = () => 10 f() // -> 10 好的,但是下面這個(gè)呢: let f = () => {} f() // -> undefined 你也許期待著返回`{}`,而不是undefined。著主要是因?yàn)榇罄ㄌ?hào)也是函數(shù)定義語(yǔ)法的一部分。如果你真想返回大括號(hào),可以這么寫: let f = () => ({}) f() // -> {} ## Math.max()比Math.min()小 Math.min(1,4,7,2) // -> 1 Math.max(1,4,7,2) // -> 7 Math.min() // -> Infinity Math.max() // -> -Infinity Math.min() > Math.max() // -> true 原因: [Why is Math.max() less than Math.min()? by Charlie Harvey](https://charlieharvey.org.uk/page/why_math_max_is_less_than_math_min) ## String不是String的實(shí)例 'str' // -> 'str' typeof 'str' // -> 'string' 'str' instanceof String // -> false 構(gòu)造函數(shù)`String`返回一個(gè)字符串: typeof String('str') // -> 'string' String('str') // -> 'str' String('str') == 'str' // -> true 如果我們用new來(lái)構(gòu)建的話: new String('str') == 'str' // -> true typeof new String('str') // -> 'object' 竟然變成了一個(gè)對(duì)象! new String('str') // -> [String: 'str'] 參考: [21.1.1 The String Constructor](https://www.ecma-international.org/ecma-262/#sec-string-constructor) ## 往期參考 - [怪異的JavaScript系列(一)](https://blog.fundebug.com/2018/04/03/javascript-werid-series-1/) - [怪異的JavaScript系列(二)](https://blog.fundebug.com/2018/04/12/javascript-werid-series-2/)總結(jié)
以上是生活随笔為你收集整理的怪异的JavaScript系列(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 软件工程作业之CSDN测评
- 下一篇: android studio json格