1

Here's an object containing a list of strings(valuesDictionnary), these strings are made readable from the outside of the object with a list of getters set as a property of the object(gettersDictionnary).

This strange structure is used to make the strings of the list unconfigurable from the outside but configurable and so removable from the inside.

var obj = new (function () {

    var gettersDictionnary = {},
        valuesDictionnary = {
            anyValue: "problem"
        };

    Object.defineProperty(this, "gettersDictionnary", {
        configurable: false,
        get: function () {
            return gettersDictionnary;
        }
    });

    Object.defineProperty(gettersDictionnary, "anyValue", {
        configurable: true,
        get: function () {
            return valuesDictionnary["anyValue"];
        }
    });

})();

Here's the point, when a "delete" instruction is sent to one of the getters("anyValue") from the outside of the object, it should ends up with the destruction of the string contained in the list given by the "return" operator, not with the destruction of the string contained in the variable gettersDictionnary. But it does.

Then I'm asking why in this case the "return" operator seems to give a reference to the variable gettersDictionnary, but not its value as it it should do.

console.log(obj.gettersDictionnary.anyValue); //"problem"

delete obj.gettersDictionnary.anyValue;

console.log(obj.gettersDictionnary.anyValue); //"undefined"

the last console.log should give "problem", why it doesn't ?

Here's the full code snippet :

var obj = new (function () {
    
    var gettersDictionnary = {},
        valuesDictionnary = {
            anyValue: "problem"
        };
    
    Object.defineProperty(this, "gettersDictionnary", {
        configurable: false,
        get: function () {
            return gettersDictionnary;
        }
    });
    
    Object.defineProperty(gettersDictionnary, "anyValue", {
        configurable: true,
        get: function () {
            return valuesDictionnary["anyValue"];
        }
    });
    
})();

console.log(obj.gettersDictionnary.anyValue); //"problem"

delete obj.gettersDictionnary.anyValue;

console.log(obj.gettersDictionnary.anyValue); //"undefined"
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Owakes
  • 11
  • 2
  • Please [never use `new function(){…}`](http://stackoverflow.com/q/10406552/1048572)! – Bergi Jul 20 '15 at 10:31
  • You [cannot `return` a reference to a property](http://stackoverflow.com/q/13124417/1048572), sorry. – Bergi Jul 20 '15 at 10:34

1 Answers1

1

Here is the semantics of the delete operator, from the Ecmascript Spec:

When the [[Delete]] internal method of O is called with property name P and the Boolean flag Throw, the following steps are taken:

  1. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
  2. If desc is undefined, then return true.
  3. If desc.[[Configurable]] is true, then
    1. Remove the own property with name P from O.
    2. Return true.
  4. Else if Throw, then throw a TypeError exception.
  5. Return false.

As you can see, the solution is make the property not configurable.

levi
  • 23,693
  • 18
  • 59
  • 73
  • Thank you for your answer, I might not have explained my problem clearly : this property cannot be set configurable because it must be removable with the operator `delete` for some reasons, but only from the inside of the object block. Therefore I have made the variable "getterDictionnary" with a read-only access thanks to the property attached to the object "obj" that should only give the value of the variable . Then, the expected result is that the delete operator apply to a copy of the "getterDictionnary" variable and then don't remove the "anyValue" property. But it doesn't work. – Owakes Jul 19 '15 at 21:52