Accessing Javascript Object Keys - javascript

I'm having the hardest figuring out how to this (seems so simple).
I have a Javascript Object as shown here
Output of console.log(data):
{"prevExists":false,"pubKey":"b5","ID":"5f1"}
I'm trying to access the different key value pairs.
When I try the expected methods, I get back undefined.
I have tried:
var pubKey = "pubKey";
data.pubKey
data[pubkey];
data["pubKey"];
I know I'm missing something really obvious here.

You have several ways of accessing keys, depending on which keys you're talking about.
In your example, any of those would work:
var data = {
"prevExists":false,
"pubKey":"b5",
"ID":"5f1"
};
// Access all keys of enumerable string-keyed properties
Object.keys(data).forEach((key) => console.log(key,data[key]));
// Access all keys of enumerable and non-enumerable string-keyed properties
Object.getOwnPropertyNames(data).forEach((key) => console.log(key,data[key]));
// Access all keys of enumerable string-keyed properties of your object, its prototype, and all the prototype chain...
for (let key in data)
console.log(key,data[key]);
If you want to have a better understanding of what is an object's property, you can have a look at this recent answer I wrote on the topic.

You can use Object.keys and a foreach loop to access the properties on the object.
var data = {"prevExists":false,"key":"b5","ID":"5f1"};
Object.keys(data).forEach(function(key) {
console.log('key - ' + key + ' :: value - ' + data[key]);
});

First you need to create a reference to your object. Like this:
var myObj = { "prevExists": false, "key": "b5", "ID": "5f1" };
Then, you can access the elements using their keys:
console.log(myObj["prevExists"]);
Console exit:
false
Good luck!

Use the Object.keys method
var data = {"prevExists":false,"pubKey":"b5","ID":"5f1"}
console.log(Object.keys(data));
Object.keys()
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 (the difference being that a for-in loop enumerates properties in the prototype chain as well).

You are confusing yourself with the line var pubKey="pubKey".
There are 2 ways to access object parameters:
const data = {"prevExists":false,"pubKey":"b5","ID":"5f1"};
// var pubKey = "pubKey"; This line is not needed
1) data.pubKey
If you use the dot operator (.), then you reference it with the key name.
2) data["pubKey"];
If you use brackets ([]), then you use the string that matches the key.
If you add the line:
const pubKey = "pubKey";
, then data[pubKey] will also work, because it evaluates to data["pubKey"]

Related

Why does a JavaScript array item created via dot notation exist but not get counted in array.length?

Although counterintuitive, it is possible to create a JavaScript array "property" using dot notation:
const arr = [];
arr.dot = "notation";
console.log(arr.dot); // "notation"
Weird, but ok. However, the array's length still registers as 0:
const arr = [];
arr.dot = "notation";
console.log(arr.dot); // "notation"
console.log(arr.length); // 0
Two questions:
Why is the array's length not impacted by the property assigned via dot notation?
Why is it possible to assign a property to an array via dot notation?
A JavaScript array is just an object. You're setting the property dot on the object.
You can confirm that an array is an object by doing:
typeof arr.
The length property is computed based on the number of numeric entries in the array.
Here's an excerpt taken from developer.mozilla.org:
Arrays cannot use strings as element indexes (as in an associative array) but must use integers. Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's object property collection. The array's object properties and list of array elements are separate, and the array's traversal and mutation operations cannot be applied to these named properties.
That dot notation is actually assigning a property to the array, not pushing a new value!
const myArray = ['apples', 'bananas'];
console.log(myArray);
myArray[2] = 'peach';
console.log(myArray);
I assume this is what made you look towards objects, which do this for assignment:
const myObject = {
id: 1,
name: 'Pig',
type: 'animal',
}
// Standard dot-notation assignment
myObject.sound = 'Oink!';
console.log(myObject);
// "Computed" assignment
myObject['emoji'] = '🐷';
console.log(myObject);
Here's a good read on the topic above https://ui.dev/computed-property-names/.
Back to the question at hand, though: why can't I do this:
const myArray = ['choclate', 'strawberry'];
myArray.pinapple = 'Tasty';
Arrays are essentially lists. It doesn't make sense to add an attribute (i.e. "describer") to a list.
Don't get me wrong - it is perfectly alright to set properties of an Array (as it is based off JavaScript objects), but it isn't used in the way that you're thinking of.
Here's an example of when I might use the "dot notation" assignment for an Array:
let zoo = ['Dolphin', 'Lion', 'Monkey'];
console.log(zoo);
// In-built property
console.log('I have', zoo.length, 'animals in my zoo!');
// Now, let's add a property "income"
zoo.income = 500;
console.log('My zoo has £%s', zoo.income);
// We can use this like a normal object property
zoo.income += 50;
console.log('My zoo has £%s', zoo.income);
// Let's create a method for when the zoo goes out of business
zoo.closeDown = () => {
zoo = [];
zoo.income = 0;
return true;
}
zoo.closeDown();
console.log(zoo);
console.log('My zoo has £%s', zoo.income);
Why would I want to do this? In this example, I could've used an object. But it's possible that it makes more sense to keep the animals in my zoo as an array, and then build up the methods and properties from there.
Okay, but how do I get a list of these properties/methods then?
const myArray = ['Foo', 'Bar'];
myArray.isCool = true;
console.log(myArray);
console.log(myArray.length);
let i;
for (i in myArray) {
console.log(i, myArray[i]);
}
The for (i in ...) syntax can be used here, as we are iterating through the properties of the array as an object. As we know from before, Arrays extend the Object class (kind of).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
length only counts the numeric properties.
Arrays are objects, so you can add other properties to them.
You don't even have to use dot notation, you can write arr["dot"] = "notation";

Can't list window.document properties - why?

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?
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);
}
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
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.

After Object.create: properties are there, but Object.keys / getOwnPropertyNames = []?

As the title says, I have hit a conceptual snag in understanding how Object.create() works.
It was my impression that, after using this method, the resulting object would inherit the values of the object passed as argument to Object.create(). In the simple example below, I can create an object and access its inherited values, I can even correctly get the prototype of the new object, however the Object.keys() array is empty!
let obj = Object.create({x: 1, y: 2});
console.log("Keys of obj:");
Object.keys(obj).forEach(function (key) {
console.log(key + ' - ' + obj[key]);
});
console.log("Prototype of obj:");
console.log(Object.getPrototypeOf(obj));
console.log("obj.x = " + obj.x);
Console result:
acg#acg:~/dev/$ node test.js
Keys of obj:
Prototype of obj:
{ x: 1, y: 2 }
obj.x = 1
(Just to eliminate any confusion: I get the same results when substituting Object.getOwnPropertyNames() for Object.keys(), by the way).
Am I misunderstanding something? Why is the keys array empty?
EDIT: Am I right in assuming that Object.keys() and Object.getOwnPropertyNames() only give me the properties directly available on an object, i.e. not inherited?
Then, I think my question is: is there a function that gives me an object's properties? (inherited or otherwise)
EDIT2: Nope -- got to traverse the prototype chain manually, as shown here:
Is it possible to get the non-enumerable inherited property names of an object?
EDIT3: According to answer from Pol Martin below, one can use a for..in construct to loop over all properties (including those inherited).
Also see https://stackoverflow.com/a/208439/7705625
Object.create has two arguments. The first one is the prototype of the created object, and a second optional parameter is an object of property descriptors.
Object.create(proto[, propertiesObject])
If you create the object passing the properties object as the first argument,
let obj = Object.create({x: 1, y: 2});
this one will become the prototype of your new object.
As Object.keys() returns an array of only its own enumerable properties, the ones you passed when constructing it won't be listed.
To create the object the way you intended, yo can use Object.assign:
let obj = Object.assign({}, {x: 1, y: 2});

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.

JS. Object in array?

I'm learning js, find this code:
var arr = [
{id: 111, now: '12.02.2014'}
];
What is this? I know that var arr = [ ... ] - array, but what is {} in array and how i can work with this data and display this ?
{} is the syntax for creating an object. It's called an object initializer, but it's frequently called an "object literal".
So what you're doing there is creating an object which has id and now properties, and putting that object into an array as its only entry.
...how i can work with this data and display this ?
To display the id, for instance:
console.log(arr[0].id);
What that does:
arr[0] - retrieve the first entry in the array. In our case, it's an object.
.id - Get the value of the id property from that object.
We could also write it like this:
var obj = arr[0];
console.log(obj.id);
Alternately, if we didn't know in advance what property we wanted but we were given a string containing the name of the property, we could use [] with the object as well:
var nameOfProperty = "id";
var obj = arr[0];
console.log(obj[nameOfProperty]);
JavaScript has both the dotted syntax (obj.id), and the bracketed syntax (obj["id"]) for accessing object properties, where with the latter you can use any string (including one from a variable).
Yes, that is an object inside an array. In truth, all values, from numbers to functions to arrays, are actually objects.
You can access this object in the same way as you would any item of an array. (arr[0])
You can then access properties of the object, for example arr[0].id.
For more about objects, take a look at Objects on MDN.

Categories