Question:
In the snippet I prepared below, I have a table with some simple data. Below the table are two labels that account for the total age of the data in the table. The first label is calculated using a common anonymous function, the second is using an arrow function.
I noticed that in the arrow function, this
is Window
, not the object that called the function, as in the other case. Because of this, the sum on the label results in NaN (Not a Number)
Reading the documentation , I came to the concept of this
lexicon, but from then on I didn't understand any more. How could I work around the situation so that the arrow function works the way I expected in these cases?
window.onload = function (){
atualizaSomaIdades();
atualizaSomaIdadesArrowFunction();
}
$('.excluir').click(function (){
$(this).parent().parent().remove();
atualizaSomaIdades();
atualizaSomaIdadesArrowFunction();
});
function atualizaSomaIdades(){
var total = 0;
var rows = $('table').find('tbody').find('tr');
rows.each(function () {
total += parseInt($(this).find('td').eq(1).text());
});
$('#idade-comum').text(total);
}
function atualizaSomaIdadesArrowFunction(){
var total = 0;
var rows = $('table').find('tbody').find('tr');
rows.each(() => {
total += parseInt($(this).find('td').eq(1).text());
});
$('#idade-arrow-function').text(total);
}
td{
border: 1px solid black;
}
.negrito{
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>Nome</td>
<td>Idade</td>
<td>Ações</td>
</tr>
</thead>
<tbody>
<tr>
<td>
João
</td>
<td>
25
</td>
<td>
<button class="excluir">Remover</button>
</td>
</tr>
<tr>
<td>
Carlos
</td>
<td>
16
</td>
<td>
<button class="excluir">Remover</button>
</td>
</tr>
<tr>
<td>
Artur
</td>
<td>
21
</td>
<td>
<button class="excluir">Remover</button>
</td>
</tr>
</tbody>
</table>
<span class="negrito">Total de idade:</span>
<span id="idade-comum"></span>
<span id="idade-arrow-function"></span>
Answer:
The lexicon this
in arrow function is very useful when working object-oriented in javascript (with classes for example). The MDN example is very practical:
function Pessoa(){
this.idade = 0;
setInterval(() => {
this.idade++; // |this| corretamente referência ao objeto Pessoa
}, 1000);
}
var p = new Pessoa();
For your case, so that this
doesn't take a more global context but rather the location of the function, you can indicate the element by changing it like this:
rows.each((index,elemento) => {
Example
window.onload = function (){
atualizaSomaIdades();
atualizaSomaIdadesArrowFunction();
}
$('.excluir').click(function (){
$(this).parent().parent().remove();
atualizaSomaIdades();
atualizaSomaIdadesArrowFunction();
});
function atualizaSomaIdades(){
var total = 0;
var rows = $('table').find('tbody').find('tr');
rows.each(function () {
total += parseInt($(this).find('td').eq(1).text());
});
$('#idade-comum').text(total);
}
function atualizaSomaIdadesArrowFunction(){
var total = 0;
var rows = $('table').find('tbody').find('tr');
rows.each((index,elemento) => {
total += parseInt($(elemento).find('td').eq(1).text());
});
$('#idade-arrow-function').text(total);
}
td{
border: 1px solid black;
}
.negrito{
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<td>Nome</td>
<td>Idade</td>
<td>Ações</td>
</tr>
</thead>
<tbody>
<tr>
<td>
João
</td>
<td>
25
</td>
<td>
<button class="excluir">Remover</button>
</td>
</tr>
<tr>
<td>
Carlos
</td>
<td>
16
</td>
<td>
<button class="excluir">Remover</button>
</td>
</tr>
<tr>
<td>
Artur
</td>
<td>
21
</td>
<td>
<button class="excluir">Remover</button>
</td>
</tr>
</tbody>
</table>
<span class="negrito">Total de idade:</span>
<span id="idade-comum"></span>
<span id="idade-arrow-function"></span>