archives

« Bugzilla Issues Index

#654 — The meanings of "absent"/"present" are unclear throughout the specification.


As "8.6.1 Property Attributes" says, a named accessor property may have four attributes: [[Get]], [[Set]], [[Enumerable]], and [[Configurable]].

As "8.10 The Property Descriptor and Property Identifier Specification Types" says, "Values of the Property Descriptor type are records composed of named fields where each field's name is an attribute name and its value is a corresponding attribute value as specified in 8.6.1. In addition, any field may be present or absent."

However, in "8.10.4 FromPropertyDescriptor(Desc)", the steps 4-a and 4-b do not check whether [[Get]] and [[Set]] are "present" in "Desc" but just access them. Is it an oversight of the specification or are we missing something here?

We tried the following code:

var o = { get abc() {} }
x = Object.getOwnPropertyDescriptor(o, "abc")
for (y in x) { document.writeln(y); }

where "15.2.3.3 Object.getOwnPropertyDescriptor" calls FromPropertyDescriptor, and an online JavaScript interpreter prints the following:

get set enumerable configurable

which suggests that [[Set]] is "present" even though we didn't define a setter. Calling the setter as follows:

x.abc(3)

results in the following error:

TypeError at line NaN: 'undefined' is not a function

which suggests that [[Set]] is "present" and its value is "undefined".

So, they are inconsisent. When 8.10 says that "any field may be present or absent", does the word "absent" mean that the field exists but its value is "undefined"? A similar question is when the step 12 of "8.12.9 [[DefineOwnProperty]](P, Desc, Throw)" says "For each attribute field of Desc that is present, ..." does the word "present" mean that the field exists and its value is not "undefined"? Yet another similar question is the step 2 of "8.10.1 IsAccessorDescriptor(Desc)": "If both Desc.[[Get]] and Desc.[[Set]] are absent, ..."

Finally, when the step 2 of "8.10.2 IsDataDescriptor(Desc)" says "If both Desc.[[Value]] and Desc.[[Writable]] are absent, then return false." we might be able to say that Desc.[[Value]] is absent if its value is undefined, but how about Desc.[[Writable]]? Its type is Boolean and its default value is false. Does the specification say that Desc.[[Writable]] is absent if its value is false?


(In reply to comment #0)
> As "8.6.1 Property Attributes" says, a named accessor property may have four
> attributes: [[Get]], [[Set]], [[Enumerable]], and [[Configurable]].
>
> As "8.10 The Property Descriptor and Property Identifier Specification Types"
> says, "Values of the Property Descriptor type are records composed of named
> fields where each field's name is an attribute name and its value is a
> corresponding attribute value as specified in 8.6.1. In addition, any field
> may be present or absent."
>
> However, in "8.10.4 FromPropertyDescriptor(Desc)", the steps 4-a and 4-b do not
> check whether [[Get]] and [[Set]] are "present" in "Desc" but just access them.
> Is it an oversight of the specification or are we missing something here?

In 8.10.4 the prose paragraph immediate before step 1 says "...ssumes that Desc is a fully populated Property Desceriptor..."


So in step, which is predicated by an IsAccessorDescriptor test we can depend upon the [[Get]] and [[Set]] fields both being present.

>
> We tried the following code:
>
> var o = { get abc() {} }
> x = Object.getOwnPropertyDescriptor(o, "abc")
> for (y in x) { document.writeln(y); }
>
> where "15.2.3.3 Object.getOwnPropertyDescriptor" calls FromPropertyDescriptor,
> and an online JavaScript interpreter prints the following:
>
> get set enumerable configurable
>
> which suggests that [[Set]] is "present" even though we didn't define a setter.
> Calling the setter as follows:
>
> x.abc(3)
>
> results in the following error:
>
> TypeError at line NaN: 'undefined' is not a function
>
> which suggests that [[Set]] is "present" and its value is "undefined".

That is correct. When creating a new accessor property 8.12.9, step 4.b.i attributes are set to their "default values" if they are absent (ie, not present) from Desc. The default values for [[Get]] and [[Set]] is undefined (Table 7).

>
> So, they are inconsisent. When 8.10 says that "any field may be present or
> absent", does the word "absent" mean that the field exists but its value is
> "undefined"?

8.10 is talking about Property Descriptor Record, in general. "Absent" simply means not there. The semantics of "absent" is contextually dependent upon other factors, particularly within 8.12.9


> A similar question is when the step 12 of "8.12.9
> [[DefineOwnProperty]](P, Desc, Throw)" says "For each attribute field of Desc
> that is present, ..." does the word "present" mean that the field exists and
> its value is not "undefined"? Yet another similar question is the step 2 of
> "8.10.1 IsAccessorDescriptor(Desc)": "If both Desc.[[Get]] and Desc.[[Set]] are
> absent, ..."

"Present" means actually there with an explicit value. "Absent" means not there.

>
> Finally, when the step 2 of "8.10.2 IsDataDescriptor(Desc)" says "If both
> Desc.[[Value]] and Desc.[[Writable]] are absent, then return false." we might
> be able to say that Desc.[[Value]] is absent if its value is undefined, but how
> about Desc.[[Writable]]? Its type is Boolean and its default value is false.
> Does the specification say that Desc.[[Writable]] is absent if its value is
> false?