Draft 3 of the spec for the Object class.  Changelog near the beginning.
(Notably this version includes draft code for __createProperty__.)

--lars


Title: The class "Object"

The class Object


NAME:                       "The class 'Object'"
FILE:                       spec/library/Object.html
CATEGORY:                   Pre-defined classes (E262-3 Chapter 15)
SOURCES:                    REFERENCES [1], [2]
SPEC AUTHOR:                Lars
DRAFT STATUS:               DRAFT 3 - 2008-03-14
REVIEWED AGAINST ES3:       YES
REVIEWED AGAINST ERRATA:    YES
REVIEWED AGAINST BASE DOC:  YES
REVIEWED AGAINST PROPOSALS: YES
REVIEWED AGAINST CODE:      YES
IMPLEMENTATION STATUS:      ES4RI
TEST CASE STATUS:           ?


CHANGES SINCE DRAFT 2 (2008-03-10)

  * Removed a "note" below

  * Fixed the spec for Object.prototype.toString (there needs to be a
    space preceding the class name)

  * Removed the optional second argument on 'propertyIsEnumerable'

  * Added the method __createProperty__


CHANGES SINCE DRAFT 1 (2008-03-05)

  * More elaborate status block above

  * Prototype methods do not delegate to the corresponding intrinsic
    methods, but to shared private methods that are also called by the
    intrinsic method.  In this fashion, prototype method behavior is
    invariant of subclassing

  * Introduction of a specification-only protocol helper::getClassName
    for overriding class names for ES3 compatibility

NOTES

  * The use of 'Private' instead of 'private' below is a workaround
    for a bug in the reference implementation (#368)


REFERENCES

[1] http://wiki.ecmascript.org/doku.php?id=proposals:enumerability
[2] builtins/Name.es in the ES4 RI

The class Object is a dynamic non-final class that does not subclass any other objects: it is the root of the class hierarchy.

All values in ECMAScript except undefined and null are instances of the class Object or one of its subclasses.

NOTE   Host objects may not be instances of Object or its subclasses, but must to some extent behave as if they are (see Host objects).

Synopsis

The class Object provides this interface:

public dynamic class Object
{
    public function Object(value=undefined) …
    static meta function invoke(value=undefined) …

    static public const length = 1

    intrinsic function toString() : string …
    intrinsic function toLocaleString() : string …
    intrinsic function valueOf() : Object …
    intrinsic function hasOwnProperty(name: EnumerableId): boolean …
    intrinsic function isPrototypeOf(value): boolean …
    intrinsic function propertyIsEnumerable(name: EnumerableId): boolean …
    intrinsic function __createProperty__(name: EnumerableId, value, enumerable:boolean=true, removable:boolean=true, writable:boolean=true): void …
}

The Object prototype object provides these direct properties:

    toString:             function () …
    toLocaleString:       function () …
    valueOf:              function () …
    hasOwnProperty:       function (name) …
    isPrototypeOf:        function (value) …
    propertyIsEnumerable: function (name) …
    __createProperty__:   function (name, value, dontEnum=undefined, dontDelete=undefined, readOnly=undefined) …

The Object prototype object is itself an instance of the class Object, with the exception that the value of its [[Prototype]] property is null.

Methods on the Object class object

new Object ( value=… )

Description

When the Object constructor is called with an argument value (defaulting to undefined) as part of a new _expression_, it transforms the value to an object in a way that depends on the type of value.

Returns

The Object constructor returns an object (an instance of Object or one of its subclasses, or a host object).

NOTE   The Object constructor is the only constructor function defined on a class in the language whose result may be a value of a different class than the one in which the constructor is defined.

Implementation

The Object constructor can't be expressed as a regular ECMAScript constructor. Instead it is presented below as a helper function makeObject that the ECMAScript implementation will invoke when it evaluates new Object.

The helper function makeObject only is invoked on native ECMAScript values. If new Object is evaluated on a host object, then actions are taken and a result is returned in an implementation dependent manner that may depend on the host object.

helper function makeObject(value=undefined) {
    switch type (value) {
    case (s: string) {
        return new String(s);
    }
    case (b: boolean) { 
        return new Boolean(b);
    }
    case (n: (int|uint|double|decimal)) { 
        return new Number(n);
    }
    case (x: (null|undefined)) { 
        return magic::createObject();
    }
    case (o: Object) {
        return o;
    }
    }
}

Object ( value=… )

Description

When the Object class object is called as a function with zero or one arguments it performs a type conversion.

Returns

It returns the converted value.

Implementation

static meta function invoke(value=undefined)
    new Object(value);

Methods on Object instances

The intrinsic methods on Object instances delegate to private methods that are also called by the prototype methods.

intrinsic::toString ( )

Description

The intrinsic toString method converts the this object to a string.

Returns

The intrinsic toString method returns the concatenation of "[", "object", a single space character (U+0032), the class name of the object, and "]".

Implementation

intrinsic function toString() : string
    Private::toString();

Private function toString(): string
    "[object " + helper::getClassName() + "]";

The helper function getClassName returns the name for the class. This method is overridden in some of the pre-defined classes in order to provide backward compatibility with the 3rd Edition of this Standard: It is overridden by the class Error.

helper function getClassName()
    magic::getClassName(this);

The function magic::getClassName extracts the class name from the object. See magic:getClassName.

intrinsic::toLocaleString ( )

Description

The intrinsic toLocaleString method calls the public toString method on the this object.

NOTE   This method is provided to give all objects a generic toLocaleString interface, even though not all may use it. Currently, Array, Number, and Date provide their own locale-sensitive toLocaleString methods.

NOTE   The first parameter to this function is likely to be used in a future version of this standard; it is recommended that implementations do not use this parameter position for anything else.

Returns

The intrinsic toLocaleString method returns a string.

Implementation

intrinsic function toLocaleString() : string
    Private::toLocaleString();

Private function toLocaleString()
    this.toString();

intrinsic::valueOf ( )

Description

The intrinsic valueOf method returns its this value.

If the object is the result of calling the Object constructor with a host object (see Host objects), it is implementation-defined whether valueOf returns its this value or another value such as the host object originally passed to the constructor.

Returns

The intrinsic valueOf method returns an object value.

Implementation

intrinsic function valueOf() : Object
    Private::valueOf();

Private function valueOf(): Object
    this;

intrinsic::hasOwnProperty ( name )

Description

The intrinsic hasOwnProperty method determines whether the this object contains a property with a certain name, without considering the prototype chain.

NOTE   Unlike [[HasProperty]] (see HasProperty-defn), this method does not consider objects in the prototype chain.

Returns

The intrinsic hasOwnProperty method returns true if the object contains the property, otherwise it returns false.

Implementation

intrinsic function hasOwnProperty(name: EnumerableId): boolean
    magic::hasOwnProperty(this, name);

Private function hasOwnProperty(name: EnumerableId): boolean
    magic::hasOwnProperty(this, name);

The function magic::hasOwnProperty tests whether the object contains the named property on its local property list (the prototype chain is not considered). See magic:hasOwnProperty.

The helper function toEnumerableId returns its argument if it is one of the member types of EnumerableId (int, uint, string, and Name) and otherwise converts the argument to string.

helper function toEnumerableId(x) {
    switch type (x) {
    case (x: EnumerableId) { return x; }
    case (x: *)            { return string(x); }
    }
}

intrinsic::isPrototypeOf ( value )

Description

The intrinsic isPrototypeOf method determines whether its this object is a prototype object of the argument value.

Returns

The intrinsic isPrototypeOf method returns true if the this object is on the prototype chain of value, otherwise it returns false.

Implementation

intrinsic function isPrototypeOf(value): boolean
    Private::isPrototypeOf(value);

Private function isPrototypeOf(value): boolean {
    if (!(value is Object))
        return false;

    let obj = value;
    while (true) {
        obj = magic::getPrototype(obj);
        if (obj === null || obj === undefined)
            return false;
        if (obj === this)
            return true;
    }
}

The function magic::getPrototype extracts the [[Prototype]] property from the object. See magic:getPrototype.

intrinsic::propertyIsEnumerable ( name )

Description

The intrinsic propertyIsEnumerable method retrieves the enumerability flag for a property with a certain name on the this object, without considering the prototype chain.

Returns

The intrinsic propertyIsEnumerable method returns false if the property does not exist on the this object; otherwise it returns the value of the enumerability flag.

Implementation

intrinsic function propertyIsEnumerable(name: EnumerableId): boolean
    Private::propertyIsEnumerable(name);

Private function propertyIsEnumerable(name) {
    if (!magic::hasOwnProperty(this, name))
        return false;
    return !magic::getPropertyIsDontEnum(this, name);
}

The function magic::hasOwnProperty tests whether the object contains the named property on its local property list. See magic:hasOwnProperty.

The function magic::getPropertyIsDontEnum gets the DontEnum flag of the property. See magic:getPropertyIsDontEnum.

intrinsic::__createProperty__ ( name, value, enumerable=…, removable=…, writable=…)

Description

The intrinsic __createProperty__ method creates a new dynamic property named name on this object, giving it the value value and attributes determined by the parameters enumerable, removable, and writable. If the property already exists, or if a non-writable property with the same name exists on an object in the prototype chain of this object, then a TypeError exception is thrown.

NOTE   The name __createProperty__ (with the leading and trailing underscores) has been chosen in order to minimize the risk of name collisions with existing content on the web.

Returns

The intrinsic __createProperty__ method returns nothing.

Implementation

intrinsic function __createProperty__(name: EnumerableId, value, enumerable:boolean=true, removable:boolean=true, writable:boolean=true): void
    Private::__createProperty__(name, value, enumerable, removable, writable);

Private function __createProperty__(name, value, enumerable, removable, writable) {
    if (!magic::hasOwnProperty(this, name))
        throw new TypeError(/* Property exists */);

    let obj = magic::getPrototype(this);
    while (obj != null) {
        if (magic::hasOwnProperty(obj, name) && magic::getPropertyIsReadOnly(obj, name))
            throw new TypeError(/* Property is ReadOnly in prototype chain */);
        obj = magic::getPrototype(obj);
    }

    this[name] = value;
    magic::setPropertyIsDontEnum(this, name, !enumerable);
    magic::setPropertyIsDontDelete(this, name, !removable);
    magic::setPropertyIsReadOnly(this, name, !writable);
}

The function magic::hasOwnProperty tests whether the object contains the named property on its local property list. See magic:hasOwnProperty.

The function magic::getPrototype extracts the [[Prototype]] property from the object. See magic:getPrototype.

The functions magic::getPropertyIsDontEnum, magic::getPropertyIsDontDelete, and magic::getPropertyIsReadOnly retrieve the attribute flags of the property. See magic:getPropertyIsDontEnum, magic:getPropertyIsDontDelete, and magic:getPropertyIsReadOnly.

The functions magic::setPropertyIsDontEnum, magic::setPropertyIsDontDelete, and magic::setPropertyIsReadOnly set the attribute flags of the property. See magic:setPropertyIsDontEnum, magic:setPropertyIsDontDelete, and magic:setPropertyIsReadOnly.

Methods on the Object prototype object

Description

The methods on the Object prototype object all perform simple type adjustments and then perform the same actions as the corresponding intrinsic methods.

Returns

The prototype methods return what their corresponding intrinsic methods return.

Implementation

prototype function toString()
    this.Private::toString();

prototype function toLocaleString()
    this.Private::toLocaleString();

prototype function valueOf()
    this.Private::valueOf();

prototype function hasOwnProperty(name)
    this.Private::hasOwnProperty(helper::toEnumerableId(name));

prototype function isPrototypeOf(value)
    this.Private::isPrototypeOf(value);

prototype function propertyIsEnumerable(name)
    this.Private::propertyIsEnumerable(helper::toEnumerableId(name));

prototype function __createProperty__(name, value, enumerable=undefined, removable=undefined, writable=undefined)
    this.Private::__createProperty__(helper::toEnumerableId(name),
                                     value,
                                     enumerable === undefined ? true : boolean(enumerable),
                                     removable === undefined ? true : boolean(removable),
                                     writable === undefined ? true : boolean(writable));
_______________________________________________
Es4-discuss mailing list
Es4-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es4-discuss

Reply via email to