The Art of Readable Code && High Performance Comments

Javascript 這幾年猛烈發展,然而它的某些語法特性則讓人困惑;近期在 JSDC 2013 與 Web_Design 版看見關於比較 (>, <, >=, <=, == / !=) 規則的問題,決定整理備忘。章節編號均參照 ECMA-262

Comparison Operators

lref op rref, op in [>, <, >=, <=]

  1. Operator 兩邊的運算子評估後以 GetValue 取值比較;先 GetValue(lref) 後 GetValue(rref)
  2. 依照 op 決定如何將參數 (lref, rref) 對應為 (x, y) 並解釋 r <- x < y 運算式求得之 r (11.8.1-4, step 1-4)
  3. 11.8.5 規定了 Abstract Relational Comparison Algorithm,但我不理解其中 LeftFirst 的運作方式:若 op in [<, >=],會先計算 px = ToPrimitive(x, hint Number);否則先計算 py = ToPrimitive(y, hint Number)。
    規範中定義兩次轉換:x — ToPrimitive(x, hint Number) –> px — ToNumber(px) –> nx,再由 nxny 進行比較;然而以下列程式碼測試時,nxny 是在 11.8.1-4 內的步驟 1, 3 求值,因而未受步驟 5 加入的 LeftFirst flag 影響。
    這或許與 js 內未提供 ToPrimitive 的對應接口有關。 
  4. 依照下列規則,計算 px < py 之運算結果 (Abstract Relational Comparison) r:
    1. 若 px 與 py 不全為字串:
      1. nx = ToNumber(px), ny = ToNumber(py)
      2. 若 isNaN(nx) or isNaN(ny) return undefined
      3. 若 nx == ny (註:Infinite, +0, -0 的相等亦屬於此類) or nx, ny in [+0, -0] return false
      4. 若 nx is Infinite return false
      5. 若 ny is Infinite return true
      6. 若 ny is -Infinite return false
      7. 若 nx is Infinite return true
      8. nx 與 ny 為非 0 數值,return nx < ny
    2. 若 px 與 py 全為字串:
      1. 若 px 以 py 開頭 (包含相等) return false
      2. 若 py 與 px 開頭 (相等的情況已在 i. 排除) return true
      3. 找出 px 與 py 第一個不同的字元碼 (cx, cy),return cx < cy

Equality Operators

x op y, op in [==, !=]

  1. 若 op 為 != 則回傳 !(x op y)
  2. x, y 型別 (ECMA 這邊把 null 也當成型別,但在實作裡是屬於 object) 相同:
    1. 型別為 undefined, Null,return true
    2. 型別為 Number:
      1. 若 x 或 y 為 NaN 則 return false
      2. 若 x 與 y 數值相同則 return true
      3. 若 x, y 分別為 +0 與 -0 return true
      4. return false
    3. 型別為 String,若所有字元相等則 return true; 否則 return false
    4. 型別為 boolean,若 x 與 y 同為 true 或 false 則 return true;否則 return false
  3. 若 x, y 分別為 null 與 undefined,return true
  4. 若 x, y 分別為 String 與 Number,轉換為 Number 再比較 (參照 9.3.1)
  5. 若 x, y 其中一者為 boolean,將它轉換為 Number (false->0, true->1) 再比較
  6. 若 x, y 其中一者為 String 或 Number,而另一者為 Object,則以 ToPrimitive() 將 Object 轉換為其它型別再行比較
  7. return false

讀到這邊總算了解 Folio 在 JSDC 2013 提到的的 Date object 行為特異之處:

ECMA-262 8.12.8 提到如何透過 ToPrimitive 提取 Object 的 DefaultValue 並轉換為基本型別:若有 hint (String | Number) 則優先調用 toString (String) 或 valueOf (Number) 方法;在未提供 hint 時,Date 物件優先採行 String,而其它 Object 則是 Number。

發表迴響

分類

%d 位部落客按了讚: