-
-
Save leobalter/092fc36adccfcc86e8e7b074817078e1 to your computer and use it in GitHub Desktop.
// Motivation: we need a reverse iterator for list objects. | |
// For Arrays, only reduceRight or decrementing loops | |
// Currently impossible in Map/Set without a full loop or storing the list into an Array | |
// Goal: a iterator that allows looping through the elements of a list from the last to the first element. Similar to .values() | |
// Goal: it should not change the original array | |
// Goal: it should allow interrupting the iteration. | |
// Question: Should add equivalents to keys and entries? | |
// Question: Names for the methods? | |
Symbol.reverse = Symbol('reverseIterator'); | |
function *reverse() { | |
if (!this || typeof this !== 'object') { | |
throw new TypeError('this is not an Object'); | |
} | |
const arr = this; | |
let { length } = arr; | |
while (length) { | |
length = --length; | |
if (!Object.prototype.hasOwnProperty.call(arr, length)) { | |
continue; | |
} | |
yield arr[length]; | |
// Dynamically jump to the last item in the array if it's shorter | |
if (arr.length < length) { | |
length = arr.length; // .next will jump to the latest existing value | |
} | |
} | |
} | |
Array.prototype[Symbol.reverse] = reverse; | |
var array1 = [1, 2, 3, 4, 5]; | |
console.log([...array1[Symbol.reverse]()]); // [5, 4, 3, 2, 1]; | |
var obj = { | |
length: 7, | |
6: 'a', | |
get 5() { this.length = 1; return 'b'; }, | |
4: 'z', | |
1: 'z', | |
0: 'c' | |
}; | |
console.log([...Array.prototype[Symbol.reverse].call(obj)]); // [ 'a', 'b', 'c'] | |
var array2 = [1,,2,,,3]; | |
console.log([...array2[Symbol.reverse]()]); // [ 3, 2, 1 ] | |
/* ------------------- */ | |
// As methods: | |
Array.prototype.reverseIterator = Array.prototype[Symbol.reverse]; // Needs bikesheding on the name!!! | |
// Map and Set not drafted here | |
Map.prototype.reverse = Map.prototype[Symbol.reverse]; | |
Set.prototype.reverse = Set.prototype[Symbol.reverse]; |
This is not the “proposal source”
It currently is, though -- this gist is the only thing that the agenda linked to, until the slides (which mostly contain the same info) were added. My point is exactly that: proposals should meet the entrance criteria before asking for stage advancement, and each of the criteria should be addressed in the repository/gist/README.
There is no requirement in the process document for it appearing specifically in any place including the readme; it does say "prose" which means we should indeed document things in writing somewhere, but it seemed a bit obvious since there's tons of usage in the wild of patterns like [...x].reverse()
etc, so I don't think it occurred (to me at least) that it would be necessary to spell it out.
Now that it's stage 1, we will of course create a proper proposal repo and document it the conventional way.
(worth noting that this gist also ended up linking to https://github.com/leebyron/ecmascript-reverse-iterable as well which has much more motivation documented)
This is not the “proposal source” and we plan to write down everything carefully. Please allow us a fair time considering the TC39 meeting is happening this week. I won’t use this motivation, neither rely on this gist only.