See this comment for a revised version.
The override mistake is a problem introduced with ES5's ability to mark properties as non-writable. When a property on the prototype of an object is marked non-writable, it makes the property unaddable on the object.
A notable example of this is if we freeze (which marks all properties as non-writable) on Object.prototype.
Object.freeze(Object.prototype);When we do this, it becomes impossible to set toString() on any objects that don't already have a .toString().
e.g. the following fails:
"use strict";
Object.freeze(Object.prototype);
const newObject = {};
newObject.toString = () => "Some string"; // TypeErrorThis is of particular concern to the SES proposal, which needs to freeze all builtins in order to guarantee security properties.
In this proposal we propose a new descriptor member called overridable,
this member may only be present when writable is set to false.
When overridable is present, non-writable properties on the prototype will be ignored when attempting to set them.
For example the following will print 10:
"use strict";
const proto = {};
Object.defineProperty(proto, 'example', { value: 5, writable: false, overridable: true });
const object = { __proto__: proto };
object.example = 10;
console.log(object.example);For SES, we need to be able to able to freeze entire objects, but without creating the problems of the override mistake.
As such a new function will be provided called Object.harden, this method acts just like Object.freeze,
except it sets overridable: true on all descriptors (that are configurable).
For example, the following will just work now:
"use strict";
Object.harden(Object.prototype);
const object = {};
object.toString = () => "Hello world!";
console.log(object.toString()); // Hello world!QUESTION: Should this simply be an option to freeze rather than a new method?
If we expose overridable: boolean as a new property on descriptors returned from Object.getOwnPropertyDescriptor(s),
will existing code break?
If so, should we add a new method to get overridable to Object (e.g. Object.getIsOverridable(object, name)), or should we expose overridable
only when it is set to true.
Do you mean, only when set to false? Either way, I'd expect it to be allowed to be
falseexplicitly, otherwise conditionally setting it to a boolean value gets a bit awkward.How would/could this proposal be polyfilled?