2011年5月24日火曜日

PropertyDescriptorと[[extensible]]属性の関係

PropertyDescriptor自体の説明はES5, Property Descriptor解説 - 枕を欹てて聴くを見るのがいい。
obj.testPropertyみたいにアクセスするとき、 key -> valueという率直な関係ではなくてES3では見えなかったPropertyDescriptorというものが間にあり

key -> Property Descriptor
| attributes
| value
というvalueへの紐付けがおこなわれている。
そしてPropertyDescriptorは6つのフィールドを持っていて、これをES5ではObject.definePropertyなどで設定できるという標準化がされている。
  • Enumerable
  • Configurable
  • Writable
  • Value
  • Get
  • Set

この辺の解説はES5, Property Descriptor解説 - 枕を欹てて聴くを見ましょう。

で、これとは別(とは言うけど一緒に紹介されてる事多い)にオブジェクトの[[extensible]]という属性値があり、その値はObject.seal / Object.freeze / Object.preventExtensionsで変更できる。
Object.freeze ではPropertyDescriptorのwritable:false, configurable:false と さきほどの[[extensible]]の値をfalse(オブジェクトを拡張できなくする)にする。

ここで疑問に思ったのが、Object.freezeみたいにPropertyDescriptorと[[extensible]]を一緒に変更したりしてるのに、なぜObject.defineProperty(など)で[[extensible]]は設定できないんだろ?とか思った。

PropertyDescriptor
あまり参考にならないイメージ図

よくよく考えれば当たり前で、Object.definePropertyはProperty(Descriptor)を操作するもので、PropertyDescriptor内に[[extensible]]があるわけではないので、そういうものなんだろなと。
[[extensible]]はプロパティではなくオブジェクトにあるというイメージで。(JavaScriptでは全てがオブジェクトというアレが、ちゃんと仕様を読んでない人にはややこしくさせてる気がする)

0 コメント:

コメントを投稿