這也是一個歷史原因的 Bug (historical wart)。
Javascript 試圖假裝「宣告不是很重要」,你可以有其他權宜之計(work around it)
(JavaScript trying to pretend as if the absence of a declaration isn't that big a deal)
Kyle Simpson 認為,這個部分不應該這樣做,應該 returned a string undeclared
.
it's never been created in any scope that we have access to
undefined 表示我們宣告一個變數,不過在這時候還 沒有賦值(no value).
uninitialized
(尚未初始化) aka TDZ (temporal dead zone)
因為沒有 Undeclared ,產生一個在 ES6 之後最常見的 Error 。
uninitialized 想法是,有一個 block 的作用域,那塊作用域不能被宣告,甚至「不能被 undefined」,任何操作都是禁止的。
如果你嘗試操作那一塊 uninitialized 狀態的區域,那你會得到錯誤,那個錯誤就是 TDZ 錯誤。
這邊 Kyle Simpson 把常見的 var x
「預設值是 undefined」 , 開始回推變數週期。
如果可以,javascript 一定要宣告,那這樣的話沒有宣告的變數就是 Undeclared,代表「變數沒有被建立」。
ES6之後,一個狀態 uninitialized ,「存在」有一個變數但是「還沒有被初始化」,這時候大家都不能碰,否則就是TDZ Error。
這是我自己理解畫的圖:
這邊還沒有實際提到 TDZ , 因為是 scope 才會比較詳細提到。
還要多補充一個東西,因為 Undeclared 不存在,如果在非嚴格模式底下,JS 會自作聰明的幫你宣告,這就是常常聽到 hoisting 的感覺,不過 hoisting 也是後面文章的內容。
來自 IEEE 754 規範。 IEEE 754 定義
(NaN ≠ x) = false
.
不要理解成 Not a Number 的縮寫,理解成Invalid number
。
要理解 NaN ,應該想成 NaN 是一個 警戒值(sentinel values),表示 Invalid number
數字無效的狀態。
*註:警戒值(sentinel values): 比如迴圈的終止條件寫 -1,這時候不是真的有一個值會是 -1,只是一個用來判斷終止條件的「狀態」。
為甚麼會說 Invalid number 比起 Not a Number 是更好的解釋?
number
還是 number。
NaN === NaN // false
。順帶一提,整個 js 只有這組特殊值 自己不等於自己
IEEE_754 規範 spec 明確指出 : NaN 與任何浮點數(包括自身)的比較結果都為假,即 (NaN ≠ x) = false.
line 1 : 用8進位表示數字
補充: 其他表示法
let bi = 0b11111111; // binary form of 255
let oct = 0o377; // octal form of 255
let hex = 0xFF; // Hexadecimal form of 255
let samehex = 0xff; // (the same, case doesn't matter)
alert( a == b ); // true, the same number 255 at both sides
alert( a === b ); // true, the same number 255 at both sides
line 3 : 如果我沒有貓,我沒有任何數學形式可以表示。
有人會用 0
,但數學上 0 絕對是有很重要意義的單位,不應該用來表示 「沒有」的佔位符號 (place holder)。數學上不合理,程式中也不合理。
所以 IEEE 的標準裡面才會實現特殊但有意義的值(special bit pattern)來清楚呈現。
Reference: wiki
line 6 : IEEE754 定義 (NaN ≠ x) = false.
line 10:
isNaN(var) 。var 在比對以前,也會強制轉型成數字,所以字串被轉型成 NaN
line 12,13:
很顯然強制轉型是一個爛想法(參考 line 10 強制轉型),所以 ES6 以後可以透過 Number.isNaN
做不轉型的比對。
一般來說(IEEE 754),回傳拿到 NaN 是在純數字運算
但是回傳不是數字
,所以回傳 Invalid number a.k.a. NaN。
有人就抱怨不應該存在 或 不應該使用 NaN 當作回傳,那麼你要設計什麼回傳?
如果今天沒有 NaN,那今天遇到不是數字(或是 Invalid number)
的回傳,可以回傳什麼?
回傳其他型別
,你一定會後悔還沒有 IEEE 的標準
,才逼不得已。有意義
不是 沒有回傳
。所以,如果今天你設計系統,考慮使用非 NaN 的回傳時,請仔細測試它,否則你會產生其他 bug。
有負號的 0
IEEE 754 有定義
看起來很多 bug 的 negative-zero,Kyle Simpson 實際運用於判斷地圖上的移動,在位移量為零時,可以知道是不是同方向。
同樣也可以用於遊戲,因為數學上用 + , - 當作方向判斷是很常見的。
股票上也可以用類似的方法去做設計。
最大的好處是不用存兩個變數:方向,和數值
壞處是,不熟悉的人的可能會有錯誤的操作。
可以拿 gist 的 console 當作 test case.
gist 有解答 要練習直接複製 console 當 tests
ans:
找 negative-zero :
用 infinity / value => infinity or -infinity