It is the predominant opinion that built-in Javascript prototypes should not be extended (or altered in any way):
Array.prototype.empty = function () { return this.length === 0; } // don't try that
Does this rule also apply to ES2015 symbols?
const empty = Symbol("empty");
Array.prototype[empty] = function empty() { return this.length === 0; }
Since symbol
is a mix of string
(primitive, immutable) and object
(identity) there can be no object property naming conflicts by definition.
Normal object reflection is not affected by symbols:
Object.getOwnPropertyNames(Array.prototype).indexOf("empty"); // -1
But ES2015 reflection with Reflect.ownKeys(Array.prototype)
is.
So this question is mainly about how we'll use Reflect.ownKeys
and Object.getOwnPropertySymbols
in the future.
Symbols are often used to add unique property keys to an object that won't collide with keys any other code might add to the object, and which are hidden from any mechanisms other code will typically use to access the object. That enables a form of weak encapsulation, or a weak form of information hiding.
There is a clear reason why you should use prototypes when creating classes in JavaScript. They use less memory. When a method is defined using this. methodName a new copy is created every time a new object is instantiated.
Whenever we create a JavaScript function, JavaScript adds a prototype property to that function. A prototype is an object, where it can add new variables and methods to the existing object. i.e., Prototype is a base class for all the objects, and it helps us to achieve the inheritance.
JavaScript has two types of objects: function object and non-function object. Conceptually, all objects have a prototype (NOT A PROTOTYPE PROPERTY).
Yes.
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.
You want to focus on loosely binding your dependencies to support better testing (loose bindings are easier to mock) and easier maintenance (a few obvious connections are easier to document and update).
To be clear: the name collisions are just a symptom of the problems caused by tightly-bound dependencies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With