Index or key in Javascript object

Asked

Viewed 1,067 times

4

I have this situation:

const movies = {
  1: {
    id: 1,
    name: 'Planet Earth',
  },
  2: {
    id: 2,
    name: 'Selma',
  },
  3: {
    id: 3,
    name: 'Million Dollar Baby',
  },

What would these numbers be 1, 2 and 3 with two points and {} after? It is an object, so it could not have these numbers, because objects are {chaves : valor}, but there it is 1:{chaves : valor}.

Can anyone explain?

3 answers

5


In Javascript, an object is a set of several key/value pairs, separated by the two points (i.e., chave : valor).

About the keys

The key can be a string:

// a chave é uma string (está entre aspas)
let x = { 'chave' : 'valor' };
console.log(x); // { "chave": "valor" }

But it can also be used a number, that the object is created without any problem:

// a chave é um número (está sem aspas)
let x = { 1 : 'valor' };
// mas ao imprimir, vemos que a chave está entre aspas
console.log(x); // { "1": "valor" }
// isso acontece porque ela foi convertida para string
console.log(Object.keys(x)); // [ "1" ]
console.log(typeof(Object.keys(x)[0])); // string

Note that the object is created using the number as key (the 1 is without quotes). But when printing the object, it appears in quotes ("1"). This is because when a number is used as a key, it is converted to string. According to the documentation:

Any non-string Object, including a number, is typecasted into a string via the toString method.

That is, implicitly is called the method toString() which converts number to string.

So in fact, there is nothing wrong with the keys of your object, from the syntactic point of view (there is perhaps a more semantic/conceptual problem, but we’ll get there).

The only point - which may be inconvenient - is what the @Wictor Chaves mentioned: how to access these properties. While a key string can be accessed as x.chave, with numeric keys this is not possible (x.1 syntax error), and the only way is to use the brackets:

let x = { 1: 'abc', 'chave': 'def' };

console.log(x.chave); // def
// console.log(x.1); // erro de sintaxe

// assim funciona
console.log(x[1]); // abc
console.log(x['1']); // abc
console.log(x['chave']); // def

Notice what to call x[1] (with the 1 unquote) works as it is also converted to string (so it is the same as x['1']).


About the values

As for the values, they can be of any kind: number, string, boolean, array, and even another object. I mean, if I have this:

let x = {
  1: {
    id: 1,
    name: 'Planet Earth',
  }
};

console.log(x); // { "1": { "id": 1, "name": "Planet Earth" } }

// a chave "1" contém um objeto
console.log(x[1]); // { "id": 1, "name": "Planet Earth" }
console.log(typeof(x[1])); // object

Note that in 1 : { "id": 1, "name" : "Planet Earth" }, the 1 is a key, and its value is another object ({ "id": 1, "name" : "Planet Earth" }).

That is, the object x contains the key 1, whose value is another object (which in turn holds the keys id - the value of which is a number - and name - whose value is a string).

Again, from a syntactical point of view, nothing wrong here. We are only defining that one of the keys has as value another object, this is perfectly normal.


About your object itself

What might be odd is the specific shape of this object, and the fact that these numbers seem redundant. At least in the given example, the value of the key is the same as in the respective id, then perhaps it would be better to simply have an array of objects (as suggested by reply from @emilioheinz):

// array com 3 filmes (delimitado por [ ])
const movies = [
  {
    id: 1,
    name: 'Planet Earth',
  },
  {
    id: 2,
    name: 'Selma',
  },
  {
    id: 3,
    name: 'Million Dollar Baby',
  }
];

console.log(movies);

// imprimir id e name do primeiro filme
console.log(movies[0].id); // 1
console.log(movies[0].name); // "Planet Earth"

// imprimir nome e id de todos os filmes
movies.forEach(filme => console.log(filme.id, filme.name));

Notice that the delimiters became [ and ], for now movies is a array, each element being an object (which in turn has the keys id and name). And since we now have an array, we don’t need to put the keys, only the values.

The difference is that arrays start with zero index, then the first element (the film with id 1) will be movies[0], the second will be movies[1] and so on.


But if you’re getting the object movies in the given format, you can travel it smoothly:

const movies = {
  1: {
    id: 1,
    name: 'Planet Earth',
  },
  2: {
    id: 2,
    name: 'Selma',
  },
  3: {
    id: 3,
    name: 'Million Dollar Baby',
  }
};

// imprime a chave e o nome do respectivo filme
Object.keys(movies).forEach(chave => console.log(chave, movies[chave].name));

// ou esqueça a chave (já que é igual ao id) e use somente os valores
Object.values(movies).forEach(filme => console.log(filme.id, filme.name));

But I still find it kind of "weird" to have the information in this format, because for me it seems better to have an array of movies, rather than an object whose keys are the ID’s of those movies. Read on in this question, who has an interesting discussion about a case similar to yours.


Bonus

Just as a curiosity, when the documentation says that any object is converted to string when used as key, is any same object:

let x = {};

// usar função como chave
x[function() { }] = 'function';

// usar regex como chave
x[/.+/] = 'regex';

// a function e a regex são convertidas para string
console.log(x); // { "function() { }": "function", "/.+/": "regex" }

The only restriction is that you can’t use the function and regex directly (doing something like x = { /.+/ : 'regex'}, because it gives syntax error). But using the brackets, it is perfectly possible, as strange as it may seem. But it is not at all useless, there’s always someone who finds some use for such things.

  • 1

    Sensational! [+1], I even wanted to create a question about the bonus, so you can talk more about the theme.

  • 1

    @I think that would be an interesting question. Just do not know how much I would contribute, since it is a feature that I do not use much, but anyway, I think valid, because doing a quick search, I did not find any specific question about it here on the site...

3

What you said is correct Objects consist of key: value, but think of it this way:

You have several objects inside each other, ie Movies is an object that has several objects inside it (1, 2, 3), these in turn have their attributes, id and name.

OBS: It is not very appropriate to use the numbers instead of the key.

You could use it as follows, making an array of objects:

const movies = [
  {id: 1, name: 'Planet Earth' },
  {id: 2, name: 'Selma'},
  {id: 3, name: 'Million Dollar Baby' }
]

Thus you would have access to each object through the array and therefore to each of its attributes, as exemplified below, not to mention that it is much easier to work and understand the data.

movies[0].id
movies[0].name

I hope I’ve helped, anything just ask here!!

3

Speaking a little of your example

You’re still an object, as you said yourself in the question

{chaves : valor}

Only in this case the numbers are the "keys" and the "values" are the objects

A small demonstration

See this example, "1" is represented in the same way as "key"

var objeto = {
  chave: "valor",
  1: "outro valor"
}
console.log(objeto);

Problem

However we have a problem when using a key with a numeral, see the example

objeto = {
  chave: "valor",
  1: "outro valor"
}

console.log(objeto["chave"]);
console.log(objeto.chave);
console.log(objeto["1"]);
//console.log(objeto.1);

Note that we can access the key as a parameter objeto.chave, or with its index, but if we do this with a numeric key a syntax error will be returned.

objeto = {
  chave: "valor",
  1: "outro valor"
}

console.log(objeto["chave"]);
console.log(objeto.chave);
console.log(objeto["1"]);
console.log(objeto.1);

"Syntaxerror: Missing ) after argument list"

Speaking briefly of keys

In Literal Object, keys can be single quote strings, double quotes, no quotes, variables, or Symbols. Source

Browser other questions tagged

You are not signed in. Login or sign up in order to post.