3

I think the answer is "no", other than deleting all references to the containing object and allowing garbage collection to eventually delete all contents of the containing object.

Live Example (view log output with console (hit F12 in Chrome, etc))

Code:

(function () {

    var nameValue = "uninitialized";

    Object.defineProperty(this, "name", {
        enumerable: true,
        configurable: false,
        get: function () {
            return nameValue;
        },
        set: function () {
            console.log("This is a read-only property");
        }
    });
    console.log(nameValue);
    nameValue = "George";
    delete this.name;
    this.name = "";
    console.log(this.name);
})();
dhilt
  • 18,707
  • 8
  • 70
  • 85
Xitalogy
  • 1,592
  • 1
  • 14
  • 17
  • Yes, that's right. Yet by `read-only` I would have expected a `writable:false` data property instead of a accessor property that doesn't change. – Bergi Oct 25 '12 at 13:14
  • 1
    Notice how I change the value of the name property internally to the closure using the underlying variable and pass in no initial parameter - this design pattern only makes sense if you use a get that returns the internal variable (not property) that underlies the property that can be altered internally. Using a getter or setter disallows use of writable and sets writable automatically to false. In doing this, i have hidden the data but allowed internal manipulation with ability to control internal object state. – Xitalogy Oct 25 '12 at 16:55

2 Answers2

5

configurable true if and only if the type of this property descriptor may be changed and if the property may be deleted from the corresponding object. Defaults to false.

Object.defineProperty on MDN

So I would agree with you that it cannot be done.

As you mention you could delete the whole object and if you first copy all the configurable properties you will, in effect have deleted them. If you do do this be aware that any other references to the original object will not be affected.

fregante
  • 29,050
  • 14
  • 119
  • 159
HBP
  • 15,685
  • 6
  • 28
  • 34
4

This answer happens to be the first result on the same query for TypeScript, so I will add that in case of TypeScript, with a class like this:

export default class Demo {
  public readonly demo: string = 'demo';

  public clear() {
    delete this.demo;
  }
}

You will get this error from TypeScript: The operand of a delete operator cannot be a read-only property.

A workaround for this is unfortunately the classic: delete (this as any).demo.

…This is of course unless you are willing to make your property read-write.

I should also add that this is very different from the JavaScript case, because TypeScript will not emit Object.defineProperty, it will emit this.demo = 'value', so you are not fighting the runtime problem the OP has, but a compile time one where it is the TS compiler and it's type system looking out for you instead of the JS runtime.

The reason these two cases happen to coincide when googling for it is just that they share the same nomenclature.

Tomáš Hübelbauer
  • 9,179
  • 14
  • 63
  • 125