简体   繁体   中英

Why can't I get properties count of navigator object in JavaScript?

Run in your browser (ES5+)

var propCount = Object.keys(navigator).length;
console.log(propCount); // 0

If you do it for a plain object like that

let obj = {
    foo: 'bar',
    breaking: 'bad'
}

let propCount = Object.keys(obj).length;

console.log(propCount); // 2

Why does it happen?

Sorry if it might relate to another problem like when Object.keys(obj) is only counting it for simple objects which do not contain functions/arrays , but this the 1st time I encountered with it.

And would like to know the reason of it.

Object.keys() function returns properties of the object that are directly assigned to it. If you do the following:

console.log(navigator.hasOwnProperty('permissions')); // false

If you want to see properties of navigator do the following:

for(let i in navigator){
    console.log(i);
}

It will list all the properties of navigator object because for ... in ... loop includes object's prototype.

That's because most properties of navigator are set on the Navigator prototype, which the navigator instance inherits, and Object.keys only returns the properties set on the navigator object itself.

You can get those properties from the prototype with this:

Object.keys(Object.getPrototypeOf(navigator));

On a side note, Firefox has the following properties in the navigator object itself:

[ "doNotTrack", "mozPay", "mozContacts", "mozApps" ]

There are enumerable and non enumerable properties in javascript. Object.keys() would return the enumerable own properties of an object. So in navigator object, it seems that there is no enumerable own properties. Hence Object.keys(navigator) is returning an empty array.

From the doc,

The Object.keys() method returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop.

If you want to list out all the enumerable and non enumerable properties of a certain object, then you have to write your own logic by using Object.getOwnPropertyNames() .

Note : getOwnPropertyNames will return both enum/non enum own properties of an object.

function getAllProps(obj, props = []){
 if(Object.getPrototypeOf(obj) == null){ return props; }
 return getAllProps(Object.getPrototypeOf(obj),
           props.concat(Object.getOwnPropertyNames(obj)));
}

console.log(getAllProps(navigator));
//This will give you all the properties.

If you use for..in loop then that will give you only the enumerable properties across the prototype chain. And you will have to miss the non enumerable properties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM