3

Running this JavaScript lists in Firefox 60.2 only one property ("location"), but there are many others, like "document.title" etc.

window.console.log("List props: " + Object.keys(window.document).sort().join(' / '));

Why is it this way? Safety? How is this done technically? How can I list all properties?

  • Just log `document`, and you'll get all the properties. – Teemu Jun 20 '18 at 11:54
  • No. Even in Chrome 67.0 on Windows 10 only the property "location" is listed, nothing else. And no, using only "document" instead of "window.document" changes nothing at all. – Christoph Wissing Jun 20 '18 at 11:55
  • ?? I can see all the properties in FF (60.0.2) console ... `Object.keys` returns only "_the enumerable's own properties_", all the properties in `document` are not enumerable nor own, though there are much more own enumerable properties than `location` only. Maybe a bit poor wording in my first comment, I meant do `console.log(document)`, that'll show you all the properties. – Teemu Jun 20 '18 at 11:56
  • Yes! Your last comments explains what happens, thanks! Using the console was only used for reproducing the problem, but I need a more versatile solution - which is shown in an answer below. – Christoph Wissing Jun 20 '18 at 12:03
  • Hmm ... There really seems not to be more than that single own property, MDN's [Document documentation](https://developer.mozilla.org/en-US/docs/Web/API/Document) is a bit misleading, it lists the properties as they were the own properties ... – Teemu Jun 20 '18 at 12:08

3 Answers3

2

Object.keys(o) returns the own, enumerable properties of o.

  • Own: properties defined directly on o, not on its prototype chain:
  • Enumerable: a flag that controls if a given property is included when listing an object's properties.

In this case most of the keys you expect are defined on another object in in document's prototype chain:

document.hasOwnProperty("title"); // false
document.__proto__.__proto__.hasOwnProperty("title"); // true
document.__proto__.__proto__.propertyIsEnumerable("title"); // true

You can use a for... in loop to find the enumerable properties that are defined on an object or its prototype chain:

for (let key in window.document) {
  console.log(key);
}
joews
  • 29,767
  • 10
  • 79
  • 91
0

I couldn't find an official reason for it not working with window.document but it seems you can reproduce this behavior with other variables as well. The issue seems to be Object.keys() not returning everything from these variables.

If you're still trying to get all properties of document, you can still use

var props = [];
for(var prop in window.document) {
    props.push(prop);
}
console.log("List props: " + props.sort().join('/'));

Which will do the exact same thing as your approach.

Ahmed Bajra
  • 391
  • 1
  • 2
  • 14
  • This is not an issue with object.keys it is how it works – Manos Kounelakis Jun 20 '18 at 12:04
  • Object.keys() returns an array of strings that represent all the enumerable properties of the given object. – Manos Kounelakis Jun 20 '18 at 12:05
  • @ManosKounelakis [The `for...in` statement iterates over the enumerable properties of an object.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in), which is exactly like you described `Object.keys()`. So please tell me, if your definition of `Object.keys()` is the same as the MDA definition of `for...in`, then why does one of them return all attributes and the other in some cases just two of them? – Ahmed Bajra Jun 20 '18 at 13:12
0

The reason is that Object.keys() returns returns an array of strings that represent all the enumerable properties of the given object. Try this to see which properties of document are enumerable

for(let key in document){
  let isEnumerable  = document.propertyIsEnumerable(key);
  console.log(`docment['${key}'] isEnumerable?:${isEnumerable}`);
}

However as the previous answer has stated you can use a for-in loop to get all properties in an array sort them and join them

Manos Kounelakis
  • 2,848
  • 5
  • 31
  • 55