What is an Object Type(O)?

# Juriy Zaytsev (15 years ago)

When implementing ES3.1 Object.keys in ES3, one of the steps in
algorithm of Object.keys seemed a bit confusing:

...

  1. If the Type(O) is not Object, throw a TypeError exception. ...

Based on my understanding, I implemented this check as:

function isPrimitive(o) { return o == null || /^(boolean|number|string)$/.test(typeof o); }

and then simply checked for isPrimitive being false before
proceeding (otherwise throwing a TypeError). It just seemed like the
most straight forward way of doing it.

I then received a response from one of our developers that isObject
could probably be implemented as:

function isObject(o) { return typeof o === 'object' && o !== null; }

The latter example assumed meaning of "Object" literally and would
skip, say, Function objects, or MSHTML's host objects returning
"unknown" as their typeof.

I started looking into specs more thoroughly to find out what Type
really is:

5.2 says: 'Type(x) is used as shorthand for "the type of x"'

What's type of x, then?

Type (4.3.1) says: "A type is a set of data values as defined in section 8 of this
specification."

Section 8, in its turn, lists - The Undefined Type, The Null
Type, ... , and finally The Object Type (8.6)

8.6 says: "An Object is a collection of properties. Each property is either a
named data property, a named accessor property, or an internal
property."

Am I correct in my understanding that when specs say Type(O) should be
an Object, this implies that a value is not an instance of Object
but an object in a sense of a collection of properties, and that, for
example, a Function object should be considered an Object type as
well? Does the former test - !isPrimitive(o) - look like a
reasonable simulation of what ES3.1 says?

Thank you.

# David-Sarah Hopwood (15 years ago)

Juriy Zaytsev wrote:

When implementing ES3.1 Object.keys in ES3, one of the steps in algorithm of Object.keys seemed a bit confusing:

...

  1. If the Type(O) is not Object, throw a TypeError exception. ...

Based on my understanding, I implemented this check as:

function isPrimitive(o) { return o == null || /^(boolean|number|string)$/.test(typeof o); }

Yes, that's correct.

('o == null' is non-obviously equivalent to 'o === null || o === undefined'.)

I then received a response from one of our developers that isObject could probably be implemented as:

function isObject(o) { return typeof o === 'object' && o !== null; }

That's wrong; host objects and functions have Type Object.

Am I correct in my understanding that when specs say Type(O) should be an Object, this implies that a value is not an instance of Object but an object in a sense of a collection of properties, and that, for example, a Function object should be considered an Object type as well?

Yes.

# Allen Wirfs-Brock (15 years ago)

Your understand in your last paragraph is correct.

In general, the term "type" used in the specification is referring to the categorization of values defined in Section 8. One of those "types" is "object". Functions are values of the object type. The section 5.2 definition of Type(x) is correct but perhaps should be elaborated upon as: Type(x) is shorthand for "the type of x" where possible types are those defined in Section 8 (ie, Undefined, Null, Boolean, String, Number, Object, Reference, List, Completion, Property Descriptor, Property Identifier, Lexical Environment, and Environment Record).

Note that there are very few cases where a value might be either one of the "ECMAScript language types" (the first 6 types in the list above) or one the "specification types" (the rest of them) so most often Type(x) predicates in the specification is just choosing from among the language types.

The actual coding of this test is obviously implementation dependent and I'm not familiar with your specific implementation so I can't say whether or not the functions you showed are correct.

I'll think about whether or not I can easily clarify this in the specification. I've always found to definition of Type(x) to be obscure and hard to find.

# Juriy Zaytsev (15 years ago)

On Mar 7, 2009, at 1:53 PM, Allen Wirfs-Brock wrote:

Your understand in your last paragraph is correct.

In general, the term “type” used in the specification is referring
to the categorization of values defined in Section 8. One of those
“types” is “object”. Functions are values of the object type. The
section 5.2 definition of Type(x) is correct but perhaps should be
elaborated upon as: Type(x) is shorthand for “the type of x” where
possible types are those defined in Section 8 (ie, Undefined, Null,
Boolean, String, Number, Object, Reference, List, Completion,
Property Descriptor, Property Identifier, Lexical Environment, and
Environment Record).

Note that there are very few cases where a value might be either one
of the “ECMAScript language types” (the first 6 types in the list
above) or one the “specification types” (the rest of them) so most
often Type(x) predicates in the specification is just choosing from
among the language types.

This explains it perfectly! Thank you.

The actual coding of this test is obviously implementation dependent
and I’m not familiar with your specific implementation so I can’t
say whether or not the functions you showed are correct.

My initial test tries to rule out exactly all of the "ECMAScript
language types" except an Object one - Undefined, Null, Boolean,
String and Number. I think of these types as of "primitives",
therefore isPrimitive function name : ) If a value passed to
Object.keys is in a subset of these "language types", then my test
should work properly. If, on the other hand, a value is one of the
"specification types" - there will be false positives. From what I
understand, I shouldn't worry about specification types, as none of
them seem to be able to make its way as an argument of Object.keys.
Am I correct?

I’ll think about whether or not I can easily clarify this in the
specification. I’ve always found to definition of Type(x) to be
obscure and hard to find.

That could be beneficial for other people having same doubts as I have
had.

# Allen Wirfs-Brock (15 years ago)

From: Juriy Zaytsev [mailto:kangax at gmail.com] Sent: Saturday, March 07, 2009 11:32 AM ...

My initial test tries to rule out exactly all of the "ECMAScript language types" except an Object one - Undefined, Null, Boolean, String and Number. I think of these types as of "primitives", therefore isPrimitive function name : ) If a value passed to Object.keys is in a subset of these "language types", then my test should work properly. If, on the other hand, a value is one of the "specification types" - there will be false positives. From what I understand, I shouldn't worry about specification types, as none of them seem to be able to make its way as an argument of Object.keys. Am I correct?

As far as I know, there is no way for a specification type value to become an actual parameter or the this value of a function activation. However, the result of function call (if the function is a host function) and some operators may be a Reference value. That is one of the reasons ToValue calls appears where they do, including on argument expressions before they are passed.