setItem メソッドを使用するか、プロパティ アクセサーを使用すると、localStorage の反応が変わります。
これはバグですか?
それはそうではないようです。仕様から:
setItem()、removeItem()、および clear() メソッドが、ローカル ストレージ領域に関連付けられた Storage オブジェクト x で呼び出されたときに、メソッドが何かを実行した場合、Window オブジェクトの localStorage 属性の Storage オブジェクトがx 以外の同じストレージ領域に関連付けられている場合、以下で説明するように、ストレージ イベントを発生させる必要があります。
localStorage オブジェクトは、Storage インターフェイスへの参照を持つIDL 属性です。Storage インターフェイスは Object.prototype を拡張します。これにより、追加のプロパティが取り込まれ、独自のプロパティ セットも定義されます。
このsetItem
メソッドは、ストレージ リストにプロパティを格納します。また、オブジェクトのプロパティに変更があった場合、オブジェクトはイベントを発生させ、その場合はストレージ領域を更新します。
したがって、 の予期される動作setItem
は、キーと値のペアをストレージ リストに格納することです。の予想される動作getItem
は、ストレージ リストからキーに関連付けられた値を取得することです。
では、プロパティに直接アクセスしようとすると、どのような動作が期待されるのでしょうか?. この行は、キーと値のリストが「サポートされているプロパティ」として機能することを示しています。
Storage オブジェクトでサポートされているプロパティ名は、オブジェクトに関連付けられているリストに現在存在する各キーと値のペアのキーです。
これは何を意味するのでしょうか?これは、これらのプロパティがインターフェイス仕様で定義されたゲッターとセッターにマップされることを意味します。Storage の場合、インターフェイスの仕様は次のようになります。
interface Storage {
readonly attribute unsigned long length;
DOMString? key(unsigned long index);
getter DOMString getItem(DOMString key);
setter creator void setItem(DOMString key, DOMString value);
deleter void removeItem(DOMString key);
void clear();
};
SolocalStorage["x"]
は の値にマップされgetItem("x")
、これはストレージ リストの "x" の値を返し、localStorage["x"] = y
にマップされsetItem("x",y)
ます。
ただし、これらは、 overridebuiltins属性がインターフェイスに設定されてい ない限り (ストレージ用ではない)、オブジェクトにその名前のネイティブ プロパティがない場合にのみ実行されます。
[OverrideBuiltins] 拡張属性がインターフェイスに表示される場合、インターフェイスを実装するプラットフォーム オブジェクトの場合、オブジェクトに他のプロパティが存在するかどうかに関係なく、オブジェクトのサポートされるすべてのプロパティ名に対応するプロパティがオブジェクトに表示されることを示します。またはそのプロトタイプチェーン。つまり、名前付きプロパティは、そうでなければオブジェクトに表示されるプロパティを常に隠します。これは、オブジェクト自体またはそのプロトタイプ チェーンのどこかに同じ名前のプロパティがない場合にのみ、名前付きプロパティが公開されるという通常の動作とは対照的です。
そのため、プロパティについては、関数がオブジェクトで定義されている場合、リクエストで常にアクセス/設定されることを期待する必要があります。それ以外の場合は、ストレージ リストをチェックして値があるかどうかを確認し、それを変更するか返します。
要約 (TL;DR)
仕様から予想される動作、およびテスト時に判明したことは、setItem
既存getItem
のプロパティ/関数の値をキー/値のペアとして保存し、既存の値を上書きせずにそれらにアクセスすることです。localStorage["getItem"] を介してこれらの値に直接アクセスまたは変更しようとすると、代わりにローカル プロパティにヒットします。これは、「サポートされているプロパティ」仕様がデフォルトで組み込みプロパティをオーバーライドしないことを要求しているためです。