tc39/proposal-object-freeze-seal-syntax

Use syntax at root only?

Opened this issue · 4 comments

xtuc commented

Your example:

const foo = {#
  a: {#
    b: {#
      c: {#
        d: {#
          e: [# "some string!" #]
        #}
      #}
    #}
  #}
#}

The syntax looks a bit tedious to write and read to me. I'm just wondering why the freezing or the sealing is not recursive.

My proposal:

const foo = {#
  a: {
    b: {
      c: {
        d: {
          e: [ "some string!" ]
        }
      }
    }
  }
#}

or

const foo = {|
  a: {
    b: {
      c: {
        d: {
          e: [ "some string!" ]
        }
      }
    }
  }
|}

Which would behaves the same. To me it's not a regular JS Object anymore, it's an immutable record.

What do you think?

There is some complexity in handling this. For example: what does this do?

var myUnfrozenObject = { foo: 1 }

const myFrozenObject = {#
  thisIsRecursivelyFrozen: { foo: 1 },
  isThisMutable: myUnfrozenObject,
#}
xtuc commented

Yes, that's a good point.

I would expect to have myUnfrozenObject.foo frozen as well. That could be done using setters but that will probably add to much overhead.

Potentially we could (and I think I would prefer to) make the above an early runtime error, saying that the {##} style syntax only works for defining literals without copying properties, the workaround of which would be to do this:

var myUnfrozenObject = { foo: 1 }

const myFrozenObject = {#
  thisIsRecursivelyFrozen: { foo: 1 },
  isThisMutable: { ...myUnfrozenObject }, // `myUnfrozenObject` properties are copied over and frozen
#}
xtuc commented

Yes, interesting solution.

Just though about this:

function a({# b #}) {}

I would expect b to be deeply frozen since it's a read-only binding.