Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map.keys() returns empty object (4.1.1) #3107

Closed
RobAtticus opened this issue Sep 28, 2015 · 15 comments
Closed

Map.keys() returns empty object (4.1.1) #3107

RobAtticus opened this issue Sep 28, 2015 · 15 comments
Labels
util Issues and PRs related to the built-in util module.

Comments

@RobAtticus
Copy link

Calling keys() on a Map returns an empty object rather than the keys of the Map:

$ node --version
v4.1.1
$ node
> const x = new Map();
undefined
> x.set("a", 1);
Map { 'a' => 1 }
> x.keys();
{}

This works in Chrome45 which is using a similar v8 (V8 4.5.103.35):

> const x = new Map();
undefined
> x.set("a", 1);
Map {"a" => 1}
> x.keys();
MapIterator {"a"}
@vkurchatkin
Copy link
Contributor

It's not an empty object, it's just how console represents iterator object

@vkurchatkin vkurchatkin added the util Issues and PRs related to the built-in util module. label Sep 28, 2015
@RobAtticus
Copy link
Author

Ah I see, I also realize I was using the wrong paradigm to iterator over it which is why it seemed empty to me.

This can be closed unless you think the representation should be updated.

@bnoordhuis
Copy link
Member

Suggestions on how to improve it? I'm actually not sure what a good way is of detecting iterator objects apart from V8 specific magic like %_ClassOf(it) === 'Map Iterator'.

@vkurchatkin
Copy link
Contributor

Well, Object.prototype.toString reports [object Map Iterator]

@bnoordhuis
Copy link
Member

I don't think that's tamper resistant enough. With --harmony_tostring:

> var it = { [Symbol.toStringTag]: 'Map Iterator' }
undefined

> Object.prototype.toString.call(it)
'[object Map Iterator]'

> %_ClassOf(it)
'Object'

@vkurchatkin
Copy link
Contributor

@bnoordhuis right, but the same applies to RegExp, Date, etc, and we really use this approach with them

@vkurchatkin
Copy link
Contributor

Also we can use mirrors, they are already used to inspect promises

@bnoordhuis
Copy link
Member

the same applies to RegExp, Date, etc

Yes, but that's a) a status quo appeal, and b) code that predates ES6.

we can use mirrors, they are already used to inspect promises

That's not a bad idea although it might be slow for large object graphs. I suppose we could test with v8::Value::IsMapIterator() and v8::Value::IsSetIterator() before creating the actual iterator mirror.

@vkurchatkin
Copy link
Contributor

@bnoordhuis didn't know about those, if we have them, then why use mirrors? though we could probably take advantage of preview method to show iterators content, I bet it's what Chromium does

@bnoordhuis
Copy link
Member

That sounds plausible. We use a promise mirror for the same reason, so we can print the status.

In case you're wondering why we're not using v8::Value::IsPromise() now: we can use Debug.ObjectIsPromise() in JS once we upgrade V8.

@thefourtheye
Copy link
Contributor

Ben, why Debug.ObjectIsPromise() is better?

@bnoordhuis
Copy link
Member

It's faster and creates less garbage than Debug.MakeMirror() or v8::Value::IsPromise().

@targos
Copy link
Member

targos commented Sep 30, 2015

Do these three methods return true for instances of class MyPromise extends Promise {...} ?

@bnoordhuis
Copy link
Member

@targos Yes.

@bnoordhuis
Copy link
Member

I just realized we don't have to wait for a V8 upgrade to switch to ObjectIsPromise(): #3130

evanlucas added a commit that referenced this issue Oct 8, 2015
Previously, a MapIterator or SetIterator would
not be inspected properly. This change makes it possible
to inspect them by creating a Debug Mirror and previewing
the iterators to not consume the actual iterator that
we are trying to inspect.

This change also adds a node_util binding that uses
v8's Value::IsSetIterator and Value::IsMapIterator
to verify that the values passed in are actual iterators.

Fixes: #3107
PR-URL: #3119
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
util Issues and PRs related to the built-in util module.
Projects
None yet
Development

No branches or pull requests

5 participants