Array.prototype.contains solutions

Domenic Denicola domenic at domenicdenicola.com
Tue Sep 30 16:58:55 PDT 2014


This is a follow-up thread to discuss how to solve the problem identified in http://esdiscuss.org/topic/having-a-non-enumerable-array-prototype-contains-may-not-be-web-compatible without breaking the web. (Any arguments that it is OK to break sites using MooTools, please stay in that thread and respectfully do *not* reply to this one.)

---

So, guess that proves I should never say "this will be easy!" before working on a feature. Yay, the web.

I see a few options:

1. Rename. The leading candidate would be `Array.prototype.has`. I outlined in [1] why `contains` is better; note especially the DOM classes. But you could stretch things, especially by removing the `fromIndex` parameter, into an argument that `has` is OK. (Basically, you'd be saying that an array is more like a set than a map, and that its analogy with String is mostly accidental.)

2. Specific hacks. I am thinking of e.g. making `Array.prototype.contains` a getter, with a setter that does [[DefineOwnProperty]].

3. General hacks. I joked about @@unMooToolsables, but seriously, we could do something similar to @@unscopables of using MOP hooks to fix this problem. One idea that seems reasonable is @@enumerableWhenAssigned, so that `Array.prototype.contains` starts non-enumerable, but when you do `Array.prototype.contains = x`, it becomes enumerable. You could even generalize this into something that also fixes the override mistake [2], e.g. @@defineOwnPropertyOnAssign or @@assignIgnoresProto or similar. Or you could attack the problem at the for-in level

---

1 is tempting in its simplicity. 2 is pretty gross and we'd probably be better of throwing out the feature. 3 is intriguing, although it obviously adds complexity cost to a feature that was supposed to be trivial.

I am curious if there is any support for 3, or proposals for a better hack in that vein. Because we will also have this problem for any other prototype extensions that work in the same way, e.g. MooTools's `flatten` (which seems like something we'd likely want) or their `associate`, `link`, `getRandom`, `combine`, or `pick` (which seem less likely). And I assume the problem could extend beyond MooTools, and possibly beyond Array. (Although, Array is a special case in that we can't make any of its methods enumerable.)

Especially if we choose something more general, e.g. @@assignIgnoresProto, I could see this being a powerful tool for fighting such problems in the future, and maybe for helping fix the override mistake (although I don't understand all of the use cases involved there).

[1]: https://github.com/domenic/Array.prototype.contains/#why-contains-instead-of-has
[2]: http://wiki.ecmascript.org/doku.php?id=strawman:fixing_override_mistake



More information about the es-discuss mailing list