Date.prototype mutable internal properties

# David Bruant (14 years ago)

I just wanted to put on es-discuss the concern raised by Mark Miller [1] about mutable internal properties of Date.prototype and that it should be fixed in the next version of ECMAScript.

David

[1] code.google.com/p/google-caja/issues/detail?id=1362

# Mark S. Miller (14 years ago)

Thanks David,

Yes, this is important. The way I noticed it is that the same issue came up for the FF implementation of WeakMaps < bugzilla.mozilla.org/show_bug.cgi?id=656828>. I will be proposing

the to-be-fixed Mozilla API to the committee to become the new WeakMap proposal -- making it more consistent with Map and Set. But not at the upcoming meeting -- it's not on the agenda.

In the meantime, < google-caja.googlecode.com/svn/trunk/src/com/google/caja/ses/repairES5.js>

repairs this and many other problems encountered in today's almost-ES5 implementations. Except for this issue with Date and WeakMap, all the other repairs in that file are spec non-conformances. See the kludges list at < code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/repairES5.js#989>

for cross referencing between these repairs, various bug threads, and Sputnik/test262 test names.

# Allen Wirfs-Brock (14 years ago)

Would a better solution to simply say that Object.freeze also freeze the values of any internal properties. If there are exceptions we can explicitly identify them for the specific built-in objects. This seems like a better solution then changing a lot of built-in properties to being accessors.

Arguably, this was an oversight in drafting ES5.

Finally, please submit work items like this to bugs.emcascrpt.org as a bug against "Draft for 6th Edition". that way they won't get lost.

# Mark S. Miller (14 years ago)

On Wed, Jul 6, 2011 at 12:06 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

Would a better solution to simply say that Object.freeze also freeze the values of any internal properties. If there are exceptions we can explicitly identify them for the specific built-in objects. This seems like a better solution then changing a lot of built-in properties to being accessors.

Arguably, this was an oversight in drafting ES5.

This interpretation is workable and does lead to the right outcome in this case. However, it violates my current sense of what Object.freeze means. Currently, I think of Object.freeze as "Make this object tamper proof by its clients, and prevent its clients from using this object as a communications channel in ways not expressed by the object's author." For example, freezing a closure does not alter the assignability of the variables captured by the closure.

Were we to express Dates using classes, we'd say something like

class Date {
  constructor(...) {
    private PrimitiveValue = ...
  }
  getFullYear() {
    return ... private(this).PrimitiveValue ...;
  }
  setFullYear(year, ...) {
    private(this).PrimitiveValue = ...;
  }
}

Freezing such a date instance must not affect its private properties (See last bullet at the beginning of < harmony:classes#private_instance_members>),

or we can't conveniently use classes to create defensive objects with encapsulated mutable state.

Notice that the above code does not have the problem that the built in Date has, but for a different reason: Date.prototype defined by the above code is not a kind of Date. A (private(Date.prototype).PrimitiveValue) expression would throw a TypeError, whereas within the spec, Date.prototype.[[PrimitiveValue]] is both a valid lvalue and rvalue. Given the legacy compat constraints, I think Date.prototype should unfortunately remain a Date, i.e., with [[Class]] of "Date" and with a [[PrimitiveValue]]. However, I think Date.prototype should be a special type of Date on which all attempts to mutate its [[PrimitiveValue]] instead throw a TypeError.

Finally, please submit work items like this to bugs.emcascrpt.org as a bug against "Draft for 6th Edition". that way they won't get lost.

Will do. Thanks.