$ (this) na arrow function returns different element

3

Notice that the $(this) in each case below points to a different element:

1st) Function:

$("button").click(function(){
    $("input").val(function(){ return $(this).val(); });
});      ↑                               ↑
         ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

2nd) Arrow function:

      ↓¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯˥
$("button").click(function(){      ↓
    $("input").val(()=>{ return $(this).val(); });
});

How do you make the $(this) point to the same element that points in 1st case , that is, input ? / p>

If I do not want to use $(this) , how do I reference a variable within the arrow function that selects the $("input") ?

    
asked by anonymous 27.03.2018 / 00:47

1 answer

2

This effect you see was one of the motivators for creating the Arrow Functions.

See some quotes from documentation for this effect:

  

     

An arrow function does not define its own this (...)

     

Since the functions do not have their own this (...)

     

Do not separate this (...)

By these quotes you see that an Arrow Function does not define its own this . Instead it uses the context in which it is inserted.

It is very useful in many scenarios. I quote one of the documentation itself, although adapted:

function Pessoa() {
  this.idade = 0;

  setInterval(function crescer() {
    this.idade++;
    console.log('A idade é agora ${this.idade}');
  }, 1000);
}

let p = new Pessoa();

Notice how the example does not work because the this function defines its own crescer that is different from this . For this reason you can not access the Pessoa property.

However it will already work with an Arrow Function because the idade will be the this , which is where it is inserted:

function Pessoa() {
  this.idade = 0;

  setInterval(() => {
    this.idade++;
    console.log('A idade é agora ${this.idade}');
  }, 1000);
}

let p = new Pessoa();

Completing

Using JQuery and a arrow function, $ will never work .

Skirting the problem

Although it does not work directly with Pessoa there are ways to get around the problem

  • Capturing the selected element in a variable

    In the code that was presented, you can reproduce the same effect by first saving the element (s) obtained with the $(this) selector in a variable. Then you can use it inside the arrow function as often as you like:

    $("button").click(function(){
        const input = $("input");
        input.val(()=>{ return input.val(); });
    });
    
  • Using input

    This form works when the event.currentTarget you want to capture comes from an event, such as the click event. Unfortunately this does not fit the example that has in the question, nevertheless, I leave here for reference.

    In this case you can also capture the object representing the action event, you can get the target of the event with $(this) . This target represents the native element of JS and so to be used as a JQuery object you have to do event.currentTarget .

    Example:

const coresDisponiveis = ['red', 'green', 'blue', 'yellow', 'cyan'];
$("button").click((event) => {
    let novaCor = Math.floor(Math.random() * coresDisponiveis.length);
    $(event.currentTarget).css('background-color', coresDisponiveis[novaCor]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Clique para trocar a cor</button>
    
27.03.2018 / 01:13