Doubt about using the join method

I am doing a JavaScript Course and I have a question in one of the exercises.

The following exercise follows:

Given the following object vector:

var usuarios = [
  {
    nome: 'Diego',
    habilidades: ['Javascript', 'ReactJS', 'Redux']
  },
  {
    nome: 'Gabriel',
    habilidades: ['VueJS', 'Ruby on Rails', 'Elixir']
  }
];

Write a function that produces the following result:

O Diego possui as habilidades: Javascript, ReactJS, Redux
Gabriel possui as habilidades: VueJS, Ruby on Rails, Elixir

Tip: to traverse a vector, you must use the syntax for...of and to join values from an array with a separator, use join."

My resolution:

for (let dados of usuarios) {
  console.log("O " + dados.nome + " possui as habilidades: " + dados.habilidades.join(", "));
}

I don't I understood very well the use of the join method in this exercise. If I take it out of console.log, the result is exactly the same in the console. Am I using wrong or is the result really the same using it or not?

I gave a read in the documentation of the method, but I did not understand the use in this exercise, in case it would join those of the arrays in a single string?

Author: Luiz Felipe, 2020-03-14

2 answers

There is a difference between the two examples. Also, this behavior is not due to console.log and neither is the method join. This is done by the array method toString, which is called when concatenation is done.

As you can read in this answer , the concatenation operator (+) you are using will convert all operands to type string if one of the operands is string. This means that in the example below:

const arr = ['L', 'u', 'i', 'z'];
const str = 'As letras são: ' + arr;

console.log(str);

Since one of the operands of the + operator is string, the value of arr will be converted to string. And this happens through the toString method. In the case of arrays, the method toString it will return the array elements separated by comma.

This behavior also happens in interpolations, which also call the method toString. See:

const fake = {
  toString: () => 'Some Value'
};

console.log(`O valor é: ${fake}.`);

And if you try to convert an object that does not have a method toString, the value, an error will be thrown.

// Criará um objeto sem nenhum método em seu protótipo.
const obj = Object.create(null);

console.log(`Valor: ${obj}`); // Erro!

So there is a difference yes between using the method join and do not use it. If you do not use the join method, the values always are separated by commas. join lets you choose a custom tab.

See the difference:

const letters = ['L', 'u', 'i', 'z'];

console.log(letters.toString());
console.log(letters.join());
console.log(letters.join(', '));
console.log(letters.join(' - '));

It is also valid to mention that if no argument is passed to the join method, the separator is ,, equal to toString. Anyway, it's very similar-coincidence, but it's not the same.

 5
Author: Luiz Felipe, 2020-03-14 19:26:08

The result is not exactly the same, if you take only the join() just by to run and see that it is not. Your:

var usuarios = [
    {
        nome: "Diego",
        habilidades: ["Javascript", "ReactJS", "Redux"]
    },
    {
        nome: "Gabriel",
        habilidades: ["VueJS", "Ruby on Rails", "Elixir"]
    }
];
for (let dados of usuarios) console.log("O " + dados.nome + " possui as habilidades: " + dados.habilidades.join(", "));

And now without the join():

var usuarios = [
    {
        nome: "Diego",
        habilidades: ["Javascript", "ReactJS", "Redux"]
    },
    {
        nome: "Gabriel",
        habilidades: ["VueJS", "Ruby on Rails", "Elixir"]
    }
];
for (let dados of usuarios) console.log("O " + dados.nome + " possui as habilidades: " + dados.habilidades);

Did you notice that there is a difference? It's similar but it's not the same.

By chance printing the array is almost what you need, and if you didn't want to make the text grammatically correct you could use the default printing of the array and give the same. But it is just coincidence.

If you want to print a list of data with a specific separation you term that control on hand how it will be printed, you can not get default value. In some cases it will have to be very much in hand (imagine if the latter had to be separated with the e and not with a comma), but there are cases that changes little and the join() can solve. In this case it is assembling a text with each of the elements of the array with a separation indicated by a comma and a space.

I'll give you a hint that many people don't like. And this defines a lot how the person will evolve in the area of development. Do not believe in "worked", in coincidences. You have to understand what is happening there, otherwise it is wrong even if you have no problem at all, it is wrong because you do not know why it worked out, so it may have been coincidence. This sounds silly, but it's very important, most people who are skating in programming are in this situation because they believe in The "worked".

Nice to have asked, but beware because the premise of the question is wrong on two points, the first already said, the results are not equal. The second is a hypothesis: it is believing in The "worked". Do not make use of the fact that you have given more or less right, because the next one may not be what you need.

The documentation of the method is very clear in saying what I said here, I wouldn't even know how to say it differently. What is not of course, but the logic should indicate that the array prints in one way, there is no way you can tell how you want.

Print without concatenation

Let's do another example:

var usuarios = [
    {
        nome: "Diego",
        habilidades: ["Javascript", "ReactJS", "Redux"]
    },
    {
        nome: "Gabriel",
        habilidades: ["VueJS", "Ruby on Rails", "Elixir"]
    }
];
for (let dados of usuarios) console.log(dados.habilidades);

I put on GitHub for future reference.

Look how it's changed. For me this is one of the points I hate in JavaScript, it changes the result according to the context where the data was used. Terrible. But there's something else that most people get it wrong.

Internally what console.log() does is call a method toString() from that data type. For some reason that goes beyond my comprehension (JS always does these weird things) if you use concatenation it doesn't use the toString() and resolves to assemble the way it thinks best and it's almost what you want.

Almost everyone makes wrong use of it, but having a die printed so directly is often wrong. It makes sense in very simple data, but when it is composed the data that is generated by toString() is not for printing. This is answered in What is the function of the toString () method?.

Then we get into another question that all printed data is text, so all types need to have a toString(). Many people believe that they are printing numbers, dates, miscellaneous objects or arrays , but in fact, you only print a textual representation of the data, always, it is not possible to print the Pure Data, a unless le is already a text, which is the case of type string.

Conclusion

For your case the join() seems to fall like a glove (we are not sure because we do not have the detailed requirements, and this is the most important and another valuable tip to become a good developer, without excellent requirements, the solution will not be good). If he does exactly what he wants then he solves it.

If the requirement did not speak in detail of how it should be printed then without it it could solve too, but it gets a little worse.

 3
Author: Maniero, 2020-06-11 14:45:34