So, fundamentally, this question is Not opinion-based. I seriously pursuit this issue objectively without feeling mostly arisen from the predominant opinion - Why is extending native objects a bad practice?
and this quesion is related but unanswered questions:
Should the extension of built-in Javascript prototypes through symbols also be avoided?
The first question is already closed as they say it's opinion based, and as you might know in this community once a question is Banned, however we modified it, moderators will never bother to re-open. That is the way how the things work here.
For the second question. For some unknown reason, the question has been taken more seriously and not considered as opinion based although the context is identical.
There are two parts to the "don't modify something you don't own" rule:
You can cause name collisions and you can break their code.
By touching something you don't own, you may accidentally overwrite something used by some other library. This will break their code in unexpected ways.
You can create tight dependencies and they can break your code.
By binding your code so tightly to some other object, if they make some significant change (like removing or renaming the class, for example), your code might suddenly break.
Using symbols will avoid #1, but you still run into #2. Tight dependencies between classes like that are generally discouraged. If the other class is ever frozen, your code will still break. The answers on this question still apply, just for slightly different reasons.
Also, I've read opinions(how can we discuss such a thing here without "opinion" base?), they claim
a) Library code Using Symbols exists and they may tweak Symbol API (such as Object.getOwnPropertySymbols())
b) extending object property with Symbol is not different from non-Symbol property fundamentally.
Here, for the major rationale of untouching Object.prototype
is due to #1, almost all answers I saw claimed that and we don't have to discuss if there is no Symbol usage.
However, Using symbols will avoid #1 as they say. So most of the traditional wisdom won't apply anymore.
Then, as #2 says,
By binding your code so tightly to some other object, if they make some significant change (like removing or renaming the class, for example), your code might suddenly break.
well, in principle, any fundamental API version upgrade will break any code. The well-known fact is nothing to do with this specific question. #2 did not answer the question.
Only considerable part is Object.freeze(Object.prototype)
can be the remaining problem. However, this is essentially the same manner to upgrade the basic API by some other unexpectedly.
As the API users not as API providers, the expected API of Object.prototype
is not frozen.
If some other guys touch the basic API and modifies it as frozen, it is he/she who broke the code. They upgraded the basic API without notice.
For instance, in Haskell, there are many language extensions. Probably they solve the collision issue well, and most importantly, they won't "freeze" the basic API because freezing the basic API would brake their eco.
Therefore, I observe that Object.freeze(Object.prototype)
is the anti-pattern. It cannot be justified as a matter of course to prevent Object.prototype
extension with Symbols.
So here is my question. Although I observe this way, is it safe to say:
In case of that Object.freeze(Object.prototype)
is not performed, which is the anti-pattern and detectable, it is safe to perform extending Object.prototype
with Symbols?
If you don't think so, please provide a concrete example.