Created
September 26, 2013 10:36
-
-
Save wingo/6712480 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Assuming that for-of and proxies are available, this function will detect the | |
// version of for-of being used, and bind the std_iterator object. | |
// | |
// The return value will be one of: | |
// | |
// * 'old-spidermonkey' for currently deployed spidermonkey. This code will call | |
// y.iterator() on "for (x of y) ...", then call "next" on that iterator to yield | |
// values until next() throws StopIteration. When control exits the loop, | |
// .close() is called on the iterator. | |
// | |
// * 'old-v8' for currently deployed v8 --harmony. This is like ES6, except that | |
// the RHS is expected to already be an iterator. This V8 doesn't call @@iterator | |
// on the RHS. | |
// | |
// * 'es6' for ES6 as currently specified (2013-09-05 draft). This will call the | |
// @@iterator method on the right-hand-side (RHS) of the for-of to produce an | |
// iterator from an iterable. Then next() will be called on that iterator, which | |
// is expected to return objects of the form {value: foo, done: bool}. If done is | |
// false, foo will be bound to the iteration variable and the body will be | |
// executed, and loop back. When done is true, the loop exits. Unlike | |
// old-spidermonkey, .close() is never called on the iterator. | |
// | |
// The exact spelling of @@iterator is an issue. It is specified to be a symbol in | |
// the std::iteration module, but no currently deployed engine implements ES6 | |
// modules, and SM doesn't implement symbols. So instead SpiderMonkey will use some | |
// placeholder string, but the precise spelling of that string should not be relied | |
// on by an application. This code assumes that any key passed to the get handler | |
// of a proxy that is not 'iterator' or 'next' is actually the @@iterator symbol. | |
// | |
var std_iterator; | |
function DetectForOfKind() { | |
try { | |
for (var x of Proxy.create({get: function(obj, name) { | |
switch (name) { | |
case 'iterator': throw 'old-spidermonkey'; | |
case 'next': throw 'old-v8'; | |
default: std_iterator = name; throw 'es6'; | |
} | |
}})) | |
break; | |
throw 'error'; | |
} catch (e) { | |
return e; | |
} | |
} | |
var for_of_kind = DetectForOfKind(); | |
For the record, though we already chatted elsewhere: yep :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is this going to work ?