What's more important to me is not what features a language adds, but what restrictions a language imposes. A language with a set of restrictions that developers are familiar with will make code with more predictable behavior that's easier to follow. Some concrete examples:
- Javascript introduced let, which narrows the scope in which variables are defined to a block instead of a function. This restriction makes code easier to follow because it's easier to keep track of what variables are available at a given position in the code.
- Javascript also introduces const, which is exactly the same as let, but with more restrictions. When someone sees "const", they can know that that variable won't be reassigned, making that reader have one less thing to keep track of when reading the code - less mental overhead.
- Javascript introduced functions like
Object.freeze()
andObject.seal()
to allow code writers to easily set restrictions to what can be done with an object. When a bug happens in your code, you don't have to worry about it being caused by a missing member on a sealed object, etc.
While these restrictions are great, implementing them came at a cost, because javascript wasn't originally designed with them in mind. Take this slightly contrived example:
function sendQuery(params) {
const timeout = params.timeout
delete params.timeout
request('POST /api/some/resource', params, timeout)
}
At a glance, this function seems harmless, but if you happened to have provided a sealed object to it, then it will not behave as intended. Despite the potential oddities that arise from freezing and sealing objects, the language authors decided that the restrictions it provided outweigh the oddities it creates (and the added complexity it adds to understanding object behavior).
Allowing users to create their own custom sets of object modification rules without a clear reason to do so seems like a step backward. Such a feature imposes fewer restrictions on how an object can behave, making object behavior even more difficult to understand. We're just giving us all of the cons of such decisions in the hopes that someone, somewhere can find a pro.
I will note that these kinds of arbitrary access restrictions can be emulated with proxies though, so if someone really needed an object where properties can be added and removed but not modified, they still have the power to do so in the language. It's just not as convenient to do, which is a good thing, because that is not behavior that a code reader would expect, so it should only be done in the rarest of cases. And if there arises a common need for such behavior, libraries can be made to make such proxying easier to do, or if it's common enough, it can make its way as an official feature into the language.
With all of that said - these points are all just my opinion, and if you don't agree, that's great! It's good for there to be a variety of points of view out there. I am, after all, just some guy on the internet raddling of his own opinions.