If I understand correctly, this should be similar to Jordan's case
Original code
function putEntries(map, obj) {
Object.entries(obj).forEach(
([k, v]) => map.set(k, v))
}
const map = putEntries(new Map(), {a: 'apple', b: 'banana'})
map.get('a') // 'apple'
3rd party code
delete Map.prototype.set
delete Map.prototype.get
// delete ...
So we need to extract the methods to keep ourself safe
const {get, set} = Map.prototype
function putEntries(map, obj) {
Object.entries(obj).forEach(
([k, v]) => map->set(k, v))
}
const map = putEntries(new Map(), {a: 'apple', b: 'banana'})
map->get('a') // 'apple'
Problem 1
we may need also extract the accessor
const map = putEntries(new Map(), {a: 'apple', b: 'banana'})
map.get('a') // 'apple'
map.size // 2
delete Map.prototype.set
delete Map.prototype.get
delete Map.prototype.size
// ...
but
const {get, set, size} = Map.prototype
doesn't work
You need
const {get, set} = Map.prototype
const size = Object.getOwnPropertyDescriptor(Map.prototype, 'size').get
Too verbose, lose the simplicity of destructuring.
Problem 2
Error-prone if no corresponding accessor syntax, and bind semantic make that even worse
map->size // expect 2, but should be map->size(), so acutally return a bound func
Compare: extension proposal
const ::{get, set, size} from Map
// ...
map::size // just work
Highly consistent and simple.
If use ->
token, it could be
const ->{get, set, size} from Map
// ...
map->size // just work
I choose ::
because I feel ->
is more fit for some other usage (for example in pattern match, when PATTERN -> result
)
About separate namespace
It's an individual issue, but also have a little effect on syntax in this case
const {get, set, size} from Map // normal namespace
// ...
map->size // just work
This made the const {get, set, size} from Map
too close to const {get, set, size} = Map.prototype
which would be much error prone.
Even not consider the separate namespace semantic, ::
plus from
actually is syntax salt which help to make the intention clear and avoid mistakes.