3

When I run the following Javascript scripts

ite=Iterator(["aaa","bbb"])
ite.next()

I always got an error message as follows.

enter image description here

But it is my first next() after creating it, why the iterator stopped working? In addition, why can we omit the "new" when we create an object in Javascript? I use Javascript in MongoDB v2.2.4 client.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
user2384994
  • 1,759
  • 4
  • 24
  • 29
  • 5
    In what library did you find this `Iterator` ? This isn't standard JavaScript. – Denys Séguret May 23 '13 at 16:44
  • `StopIteration` sounds like some stuff i heard about in Python. – cHao May 23 '13 at 16:44
  • 3
    @dystroy: Wrong. https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Iterators_and_Generators – SLaks May 23 '13 at 16:46
  • I don't know. I know this from https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Iterators_and_Generators. When I asked questions about Javascript, people always ask me to read documents. OK, I read documents and learnt Iterator, but it doesn't work... – user2384994 May 23 '13 at 16:48
  • 1
    @SLaks: Kinda not wrong. It's not standard. http://stackoverflow.com/questions/12079417/javascript-iterators – voithos May 23 '13 at 16:49
  • @SLaks, yes, that's where I found and learnt it. – user2384994 May 23 '13 at 16:49
  • Yes, okay, so it's *not* standard ECMAScript, it *is* standard JavaScript. Everyone agreed? – apsillers May 23 '13 at 16:50
  • As of 2.4 the default engine is no longer spidermonkey, it is V8 – Sammaye May 23 '13 at 16:52
  • MongoDB claims that its command line client supports Javascript. If it is standard in Javascript, so ... – user2384994 May 23 '13 at 16:52
  • 2
    @user2384994: To be clear, when *most* people refer to "JavaScript", technicalities aside, they refer to the fairly-standardized subset that exists in most modern browsers. The V8 JavaScript engine has no `Iterator`. – voithos May 23 '13 at 16:54
  • 1
    Hmm this might be a bug but I don't think it is, I see the documentation specifically passes the param by reference, what if you do the same? – Sammaye May 23 '13 at 16:54
  • @voithos Dude you are forgetting one thing: HE IS NOT USING THE V8 ENGINE – Sammaye May 23 '13 at 17:00
  • @Sammaye: You're right; unfortunately, I can't even reproduce this behavior in Firefox's console... – voithos May 23 '13 at 17:01

1 Answers1

3

Basically, the Iterator that you've learned about doesn't exist in all JavaScript engines - or, more correctly, in all ECMAScript engines (JavaScript is technically the Mozilla variant of ECMAScript).

There's documentation on MDN because (surprise!) MDN most often covers the version of JavaScript used in Firefox.

The current version of MongoDB, on the other hand, uses the V8 JavaScript engine (the same one that is in Chrome), so it does not have Iterator.


Unfortunately, this does not explain why you didn't get a ReferenceError. The version of MongoDB that you are using most likely contained an engine that has Iterator available.

In testing this behavior in Firebug, I get even weirder results.

>>> ite = Iterator(['aaa','bbb']);
>>> ite.next();
// Nothing
>>>
>>> var ite = Iterator(['aaa','bbb']);
>>> ite.next();
[0, "aaa"]
>>> ite.next();
[1, "bbb"]
>>> ite.next():
// Nothing

I suspect that Firebug may be suppressing StopIteration, but I have no idea why making the Iterator a global causes it to not iterate. If someone has any insight on this, I'd be interested in hearing it.

In the meantime, you may want to try creating the Iterator as a local variable, as that was the only way I was able to get the iteration to work.

// Notice the 'var'
var ite = Iterator(["aaa","bbb"]);

Yes, as pointed out by @MikeSamuel in the comments, it appears that when the REPL attempts to display the Iterator, it actually runs it to exhaustion. This would explain why ite = Iterator(...) doesn't work (because it returns the iterator as the result of the expression, which then gets exhausted by the REPL) and why var ite = Iterator(...) works (because the result of a var declaration is undefined).

voithos
  • 68,482
  • 12
  • 101
  • 116
  • it has only used V8 by default in its latest build, before IT did use spidermonkey – Sammaye May 23 '13 at 16:53
  • 2
    Then why doesn't the call to `Iterator(...)` throw a ReferenceError? It not only succeeds, but the call to `next()` then throws a `StopIteration`, which is part of the iteration API. – cHao May 23 '13 at 16:53
  • The `[object StopItation]` is a suspiciously specific error if the engine doesn't support iterators. – JJJ May 23 '13 at 16:56
  • Infact the docs even mention the error: If a yield is not encountered during the processing of the thrown exception, then the exception will propagate up through the call to throw(), and subsequent calls to next() will result in StopIteration being thrown. – Sammaye May 23 '13 at 16:56
  • @cHao: It *does* throw ReferenceError in the online shell. http://try.mongodb.org/ – voithos May 23 '13 at 16:56
  • Don't trust that thing, it is merely jquery, use a real terminal – Sammaye May 23 '13 at 16:57
  • @voithos: What it does in the online shell doesn't matter. He's using a different version, that apparently has iterators. – cHao May 23 '13 at 16:58
  • @user2384994 This answer does not solve your problem, you ARE using spidermonkey and THIS should work – Sammaye May 23 '13 at 17:01
  • 2
    My guess is that when the iterator is created thus `ite = Iterator(...)` then the REPL tries to display its values, so exhausts it. When you do `var ite = ...` the result the REPL gets is void, so doesn't do anything with the iterator. – Mike Samuel May 23 '13 at 17:19
  • @user2384994: I think we may have found an answer. See the edit. – voithos May 23 '13 at 17:24
  • @Sammaye: I think we may have found an answer to this. – voithos May 23 '13 at 17:24
  • Ah yea, if you don't explicitly declare it...that's such a common one it is normally overlooked, good work :) – Sammaye May 23 '13 at 17:29
  • I got all of them. I'm using MongoDB 2.2.4 so the Javascript engine is spidermonkey. It's a pity the new release of MongoDB changed to V8 which removed a lot of features such as array comprehensions in addition to Iterator. Thank you all! – user2384994 May 23 '13 at 23:16
  • @user2384994 V8 is a nice move by 10gen, firstly it is multithreaded so that means much better concurrency and no global js lock on everything you do in the engine, not only that but it is a **** load faster than spidermonkey tbh :) – Sammaye May 24 '13 at 07:06