简体   繁体   中英

Undefined $(this) on nested functions

So basically I have two functions on my click() trigger.

var firstFunction = function() {
    var id = $(this).attr('id');
    alert(id);
};

var secondFunction = function() {
    //something here
};

$('#trigger').click(function() {
    firstFunction();
    secondFunction();
});

On firstFunction() I'm trying to get $(this).attr('id') but it's returning undefined .

I know it has something two do with calling multiple functions because it works when I only call one function

$('#trigger').click(firstFunction);

Sample Fiddle here

As per your existing approach this refers to Window object not the element which invoke the event.

You can use .bind()

The bind() method creates a new function that, when called, has its this keyword set to the provided value,

$('#trigger').click(function() {
    firstFunction.bind(this)();
    secondFunction.bind(this)();
})

 var firstFunction = function() { var id = $(this).attr('id'); console.log(id); }; var secondFunction = function() { //something here var id = $(this).attr('id'); console.log(id); }; $('#trigger').click(function() { firstFunction.bind(this)(); secondFunction.bind(this)(); }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="trigger">Click Me</button> 

Fiddle

It's returning undefined because you aren't applying the same this as the event. You can achieve this by using call or apply instead of calling it directly.

$('#trigger').click(function() {
    firstFunction.call(this);
    secondFunction.call(this);
});

The this inside the firstFunction will be the window object itself - pass this to the function to fix it - see demo below:

 var firstFunction = function(el) { var id = $(el).attr('id'); alert(id); }; var secondFunction = function() { //something here }; $('#trigger').click(function() { firstFunction(this); secondFunction(this); }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="trigger">Click Me</button> 

Another way is to use Function.prototype.call to bind a this argument to the funciton:

 var firstFunction = function() { var id = $(this).attr('id'); alert(id); }; var secondFunction = function() { //something here }; $('#trigger').click(function() { firstFunction.call(this); secondFunction.call(this); }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="trigger">Click Me</button> 

You can pass the jQuery object element and than only use it in your function:

 var firstFunction = function($el) { var id = $el.attr('id'); console.log(id); }; var secondFunction = function() { //something here }; $('#trigger').click(function() { firstFunction($(this)); secondFunction(); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="trigger">Button</button> 

click() handler receives event as parameter. Pass it because this is not available in the scope of firstFunction() .

Like this:

var firstFunction = function(target) {
    var id = $(target).attr('id');
    alert(id);
};

var secondFunction = function() {
    //something here
};

$('#trigger').click(function(e) {
    firstFunction(e.target);
    secondFunction();
});

Nothing to do major, it's quite simple.

If you are calling a function and into that function you need an event to be used, then pass a reference in the function parameter.

I have updated the code in your Fiddle and updated with Mine:

Step 1:

$('#trigger').click(function(event) {
  var that = this;
  firstFunction(that);
  secondFunction(that);
});

Created a variable that assigned this to that and passed into function parameter.

Note that, writing event in the click function is required to define this as a local click reference (Not a window)

Step 2:

Passed that rather than this, to make sure the reference is from click function only not of window.

var firstFunction = function(that) {
  var id = $(that).attr('id');
  alert(id);
};

Updated Fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM