As you know, obj['key']
is used to retrieve a property that's literally on the object (unless you're using proxy magic, getters, etc).
The proposed obj@['key']
operator doesn't do anything unless it is overloaded, but can be overloaded using two new, well-known symbols: Symbol.getDataValue and Symbol.setDataValue. The usefulness of an overloadable data-accessor operator will become clear with some example use cases.
If we set Map.prototype[Symbol.getDataValue]
to Map.prototype.get
, and set Map.prototype[Symbol.setDataValue]
to Map.prototype.set
, then the following would become possible:
m = new Map([['x', 2]])
m@['x'] ??= 5
m@['y'] ??= 5
console.log(m) // Map(2) { 'x' => 2, 'y' => 5 }
The "Array.prototype.at" proposal provides a convinient way to index into arrays with negative inidices. With the data accessor operator, we could provide similar functionality:
items = [5, 6, 7]
items@[-1]++
console.log(items@[2]) // 8
items@[-2] = 0
console.log(items) // [5, 0, 8]
I presume URLSearchParams is not part of ECMAScript, but whatever comittee that has juristiction over it could also take advantage of the data accessor operator:
const params = new URLSearchParams('x=2&y=3')
params@['x'] = '5'
console.log(params.toString()) // x=5&y=3
We could potentially provide a default data-access behavior for objects (by defining the new well-known symbols on Object.prototype), The default behavior can be defined similar to normal propecty access, except it only accesses own properties.
const untrustedKey = 'toString'
const mapping = { x: 1, y: 2 }
console.log(mapping[untrustedKey]) // [Function: toString]
console.log(mapping@[untrustedKey]) // undefined
Implementation Details
Here's an example of how one would go about creating their own overload for this operator, along with some examples of when these operators get called:
const customObj = {
[Symbol.getDataValue](key) {
console.log('GET', key)
return 5
},
[Symbol.setDataValue](key, value) {
console.log('SET', key, value)
},
}
customObj@['x'] // GET x
customObj@['x'] = 'NEW_VALUE' // SET x NEW_VALUE
customObj@['x']++ // "GET x" then "SET x 6"
Suggestions?
I'd love to hear any feedback on this idea, especially on these points:
- I'm certainly not set on the
obj@[key]
syntax - I just picked something random for this. If anyone has any other ideas for syntax that they would prefer, please share! - Let me know if you can think of other use cases for such an operator, I'm sure there's plenty more out there that I haven't thought of.