@@species came up on TC39's agenda in an attempt to preserve compatibility with Zepto. A patch was merged on October 21, 2014 to remove the problematic use of __proto__, but the old code can be found here. Here's the relevant snippet:
zepto.Z = function(dom, selector) {
dom = dom || []
dom.__proto__ = $.fn
dom.selector = selector || ''
return dom
}
In this old version, $.fn
is an object literal with no constructor
property. Sometimes, Z
is called with no arguments, so the default case of taking an Array
, swapping out its __proto__, and then calling Array
methods on it needs to be supported, even though dom.constructor
will be Object
(if I understand correctly).
@@species is intended to fix Zepto, but another fix is also possible: ArraySpeciesCreate could check for a constructor which is Object and fall back to ArrayCreate(0) in that case. The spec text would be, in ArraySpeciesCreate, 5.c:
5.c. If Type(C) is Object
i. If Samevalue(C, %Object%), let C be undefined
Basically all other uses of @@species could just be removed, using the constructor as the species, and this would be sufficient for maintaining compatibility with old versions of Zepto.
I've heard a fix like this was considered, but rejected. I'm not sure if this was because that other fix didn't work, or because @@species is considered a cleaner, more general solution. Does anyone in the comments remember?