Skip to content

2026-05-11

/ 10 分鐘閱讀

/ JavaScript Hard Parts v3

Date 物件的隱藏屬性 [[DateValue]] 與方括號記法動態存取

Date 物件與時間戳記

JavaScript 內建了一個 Date 函式,搭配 new 關鍵字呼叫後,會回傳一個物件,其中有一個隱藏屬性 [[DateValue]],儲存的值是從 1970 年 1 月 1 日午夜(Unix Epoch)至今所經過的毫秒數

javascript
const time1 = new Date(); // 例如 Jan 15 2027 00:00:00
// 3 秒後
const time2 = new Date(); // 例如 Jan 15 2027 00:00:03

假設 time1 建立時距 Epoch 已過了約 1.8 兆毫秒,則 time2[[DateValue]] 就是 1.8 兆加上 3000 毫秒。這個精確的時間戳記極具實用價值,例如可以用來防止使用者短時間內重複送出表單:若兩次提交之間相差不到 2000 毫秒,就拒絕第二次提交。

然而問題在於:[[DateValue]] 是隱藏屬性,無法透過 time1.dateValuetime1[["dateValue"]] 存取,且 time1time2 都是物件,儲存在 Heap 中,===== 比較的都只是記憶體位址而非內容。直接相減或比較兩個 Date 物件的做法,在 JavaScript 中行不通。

Date 物件本質上是普通物件

儘管有隱藏屬性,Date 回傳的物件在其他方面與一般物件無異,可以自由新增屬性。以下範例示範用方括號記法(square bracket notation) 動態新增屬性:

javascript
const month = 'jan';

time1[month] = true; // 等同於 time1["jan"] = true,即 time1.jan = true
time2[month] = true;

方括號記法的關鍵行為:time1[month] 中,month 不是屬性名稱本身,而是一個需要先被求值的變數。JavaScript 先查找 month 的值("jan"),再以這個值作為屬性名稱。最終在 time1 上建立的屬性是 jan,而非 month

相比之下,點記法 time1.month 會直接建立名為 month 的屬性,而不會對變數求值。這個差異在後續的元程式設計中將會非常重要:當屬性名稱本身需要動態決定時,只有方括號記法能勝任。

問題尚未解決

現在的情況是:

  • time1time2 是兩個普通物件,都存在 Heap 中,只能透過參考存取
  • 時間戳記藏在 [[DateValue]] 這個隱藏屬性中,無法直接讀取
  • 直接比較兩個 Date 物件,得到的永遠是 false

理想的做法是直接對兩個 Date 物件做減法 time2 - time1,得到相差的毫秒數。要讓這件事成為可能,需要一種機制讓開發者能手動控制物件在運算子作用時的行為,而這正是接下來要探討的主題。

複習

JavaScript 的 Date 物件是從哪個日期開始計算毫秒數的?

從 1970 年 1 月 1 日午夜(Unix Epoch)開始計算。這是 JavaScript Date 系統中毫秒計數的起始點。

使用方括號記法設定物件屬性時,例如 time1[month] = true,其中 month = "jan",實際上建立的屬性名稱是什麼?

建立的屬性名稱是 "jan"。方括號記法會先對 month 這個變數求值,取得其內容("jan"),再以這個值作為屬性名稱。變數名稱本身不會成為屬性名稱。

若第一個 Date 物件的時間戳記為 1.8 兆毫秒,3 秒後建立第二個 Date 物件,其 [[DateValue]] 是多少?

1.8 兆加上 3000 毫秒(即 1,800,000,003,000 毫秒)。因為 3 秒等於 3000 毫秒,第二個時間戳記就是原始時間戳記加上 3000。

比較兩個 Date 物件的時間戳記,有什麼實際的使用情境?

防止使用者短時間內重複送出表單。透過比對時間戳記,可以判斷使用者是否在近期(例如 2000 至 3000 毫秒內)已經按過送出,若時間間隔不足則拒絕第二次提交。

小測驗

JavaScript 的 Date 毫秒計數從哪個日期與時間開始? 1970 年 1 月 1 日午夜
執行 `time1[month]`,其中 `month` 的值為 "jan" 時,建立的屬性名稱是什麼? jan
課程中提到,比較 Date 物件時間戳記有什麼實際用途? 防止使用者短時間內重複送出表單

此文章是 FrontendMasters 上的 The Hard Parts of JavaScript 課程筆記

最後更新時間:

Buy Me A Coffee

系列章節 第 23 篇 / 共 27 篇

0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog
Photo by Federica Galli on Unsplash