Open aqrln opened 7 years ago
The solution with assigning a dynamically generated prototype to an array is elegant but I see several problems here:
Performance. Changing the prototype of an existing object is not only quite a slow operation itself but also can cause deopts in the code that references such objects.
Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of altering inheritance are subtle and far-flung, and are not limited to simply the time spent in obj.__proto__ = ... statement, but may extend to any code that has access to any object whose [[Prototype]] has been altered. If you care about performance you should avoid setting the [[Prototype]] of an object.
(source)
This can be worked around, though, by constructing a new object using Object.create(newPrototype, oldObject)
. But after this operation JSRD array will definitely not be represented as an array internally. Instead, it will be a hash map with numeric keys, in addition to string keys defined in prototype, so we get an extra overhead.
We lose some flexibility when working with such objects because it would be necessary to treat them specifically. Not much of JavaScript code expects any properties except for functions to be inherited via prototype chain so any function that relies on Object.keys()
or hasOwnProperty()
will be broken when such object is passed. For example, if we needed to iterate such object's keys, we would either need to use a slow for-in loop, or pass metadata along with the object, iterate its keys and check for corner cases such as optional keys manually.
To conclude, it will be better to construct an object instead of assigning a prototype. Such objects will not have subtle drawbacks when working with them and, even more importantly, will work significantly faster.
FYI @tshemsedinov
We will need custom prototypes, though. For functions.
Thus the basic algorithm is:
Object.create(prototype)
.
Conceptual code by @tshemsedinov copied from Impress: