$(this) in Arrow Function returns different element

Asked

Viewed 89 times

2

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

1º) Function:

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

2º) Arrow Function:

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

How to do what, in the second case, the $(this) points to the same element that points to the first case, i.e., the input?

If that’s why I shouldn’t use the $(this), how to reference a variable within the Arrow Function who selected the $("input") in question?

  • Thanks for the comment, but I really needed a conclusive reply.

  • Anyway there is the tip for anyone who can search (or even take a look at the documentation) and write something more elaborate. :)

  • Ah tah rs... thanks!

1 answer

3


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

See some quotes from documentation in relation to that effect:

Until Arrow functions, Every new Function defined its Own this value (...)

An Arrow Function does not Newly define its Own this (...)

Since Arrow functions do not have their Own this (...)

In the Second this (...)

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

It becomes very useful in several 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 function crescer defines its own this which is different from Pessoa. For this reason you cannot access the property idade.

However it will already work with an Arrow Function because the this will be the one of Pessoa, 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();

Concluding

Using Jquery and one Arrow Function, within it $(this) will never work.

Getting around the problem

Although it does not work directly with $(this) there are ways around the problem

  • Capturing the selected element in a variable

    In the code it presents, it can reproduce the same effect by keeping first the element(s) obtained(s) with the selector of input a variable. Then you can use it inside the Arrow Function as many times as you want:

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

    This form works when the $(this) that if you want to capture comes from an event, as for example the click. Unfortunately this does not fit the example you have in the question, yet I leave here as reference.

    In this case you can also capture the object that represents the action event, you can get the event target with event.currentTarget. This target represents the native JS element 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>

  • Obg for the answer. In short, there is no way to do what the question wants?

  • @dvd There is no way to do it directly. Summarizing as much as possible, there is no way to do it $(this) function within a Function array with Jquery. I updated the response with more information regarding this.

Browser other questions tagged

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