Object.create(null)

TypeError: Cannot convert object to primitive value

JavaScript のオブジェクトのキーや要素の列挙順は保証されているんですか

A. 場合によります

オブジェクトのキーまたは要素の列挙といえば次の 2 つくらいでしょう. たぶん.

  • Object.keys, Object.values, Object.entries など Object のメソッド
  • for-in

for-of は直接オブジェクトのキーや要素を列挙することはないのでここでは関係ないです.

lodash などの各種ライブラリにあるような列挙用のメソッドについてはそれらのドキュメントを参照してください. JavaScript の仕様と関係ないので.

Object のメソッド

仕様は以下.

どれも EnumerableOwnPropertyNames というのを呼び出していますね.

https://www.ecma-international.org/ecma-262/9.0/index.html#sec-enumerableownpropertynames

これを見ると [[OwnPropertyKeys]] の順番がそのまま出てくるようです. 通常のオブジェクトだとどうなっているか見てみましょう.

1. Let keys be a new empty List.
2. For each own property key P of O that is an integer index, in ascending numeric index order, do
 a. Add P as the last element of keys.
3. For each own property key P of O that is a String but is not an integer index, in ascending chronological order of property creation, do
 a. Add P as the last element of keys.
4. For each own property key P of O that is a Symbol, in ascending chronological order of property creation, do
 a. Add P as the last element of keys.
5. Return keys.

というわけで「整数キーが数値昇順, 文字列キーが作成順, Symbol キーが作成順」という順番に取得されます.

JS のオブジェクトのキーは全て文字列では? と思われた方もいることでしょう. それはそれで正しいのですが, 見ての通り整数を表す文字列のキーは特別扱いされています.

for-in

このへんですね.

https://www.ecma-international.org/ecma-262/9.0/index.html#integer-index

EnumerateObjectProperties というのを使っています.

https://www.ecma-international.org/ecma-262/9.0/index.html#sec-enumerate-object-properties

The mechanics and order of enumerating the properties is not specified

とあるので順番は定められていません. キーの取得には上でも出てきた [[OwnPropertyKeys]] を必ず使うことになっているので, まあ普通に実装したら順番そのままになりそうですが, シャッフルされていても文句は言えません.

結論

  • Object.keys, Object.values, Object.entries など Object のメソッドでは, 「整数キーが数値昇順, 文字列キーが作成順, Symbol キーが作成順」という順番が保証されている
  • for-in では順番は保証されていない

とはいえ順番が保証されているからといって不必要にそれに依存しない方がベター, というのは言うまでもないですよね.

特に工夫もない紫蘇ジュース

実家にいた頃祖母が作ってくれた紫蘇ジュースが飲みたいと思いつつ就寝, 翌日スーパーに行ったら実家付近で採れた紫蘇が大量に売られており, 運命を感じて即購入. というわけで特に工夫もない紫蘇ジュースを作った話をします.

以下, 紫蘇の鮮やかさをお伝えするため, 写真に一貫して謎のフィルタを適用しています. 代償として金属が妙に CG めいた感じになりましたがご了承下さい.


材料を揃えましょう.

  • 赤紫蘇 (てきとう) f:id:susisu:20180609220947j:plain これくらい. 祖母も分量を量っていなかったし, 特に味にムラがあったとかそういう思い出はないのでたぶん本当に適当で良いはず. 予め洗って水を切っておく.
  • 砂糖 (200 g くらい)
  • レモン汁 (50 ml くらい)
  • 水 (1 リットル弱, これは手持ちの鍋のサイズによる上限)

お湯を沸かす.

f:id:susisu:20180609221341j:plain

沸いた. このくだり本当に必要ですか?

f:id:susisu:20180609221437j:plain

紫蘇を投入.

f:id:susisu:20180609221529j:plain

赤紫蘇は色素が抜けて緑色になっていく.

f:id:susisu:20180609221552j:plain

ある程度煮出せたら出涸らし, 通称ドレミファラを適当に菜箸とかで取り出します. 細かいのは後で茶漉しで取り除くので気にしなくて良い.

これが世間一般には青紫蘇と呼ばれている物質.

f:id:susisu:20180609221613j:plain

続けて煮出した汁にこれでもかと砂糖を投入します. 大量に入れているのは保存のためで, この時点では味は気にせず飲む際に適宜調整するスタイル. 溶かし終えたら火を止める.

さて色が悪いですね. このままでも味に問題はないのですが, ここに酸を入れて見た目の改善を試みます.

f:id:susisu:20180609221638j:plain

というわけでレモン汁を投入. これは変色の様子を GIF 動画に収めたものですが, 文字が邪魔なので ☆ 1 つです.

f:id:susisu:20180609221701g:plain

風情が欲しければ生のレモンを搾っても良いし, 実家ではクエン酸をドボと投入していた. 風の噂によると酢を入れる流派もあるらしい.

Vivified.

f:id:susisu:20180609221718j:plain

適当に茶漉しで残った葉を取り除きつつ容器に移して完成. たまたま棚に眠っていたお茶用の容器が茶漉しもついていて最適だった.

f:id:susisu:20180609221746j:plain

そのままだと激甘なので, 飲む時は水で薄めてお好みの甘さにしましょう. 大体この作り方だと二倍に薄めると丁度良いくらい.

f:id:susisu:20180609221818j:plain

炭酸水で割ると爽やかさが増して, 一足先に夏が来ます.

作った紫蘇ジュースは大体一ヶ月くらい保存できるとの噂がありますが, 特に試していないので保証はしません.