4

Self invoking function defined inside jQuery event is not working, but why?

$('div').on('click', function(){
  $('div').text($('div').text() + 1)
  (function(){
    $('div').text($('div').text() + 0)
  })();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>text</div>

Edit: Answers below are focused on this keyword so I've changed this parameter to 'div'. It still does not work.

vter
  • 1,881
  • 1
  • 20
  • 38

3 Answers3

4

Inside that IIFE the this refers to another context. Each function has it's own context. You can use arrow function, explicitly binding of the context or just keep this reference into another variable and use it. One more thing, you missed to put ; after the first statement, this will cause an error.

Also don't use this style in that code $('div'), this will find all divs but get the text of the first one, so you do more job than it needs.

Arrow function

$('div').on('click', function() {
    $(this).text($(this).text() + 1);
    (() => {
      $(this).text($(this).text() + 0)
    })();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>text</div>

Explicit binding of the context

$('div').on('click', function(){
    $(this).text($(this).text() + 1);
    (function() {
        $(this).text($(this).text() + 0)
    }).bind(this)();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>text</div>

Keep the reference into another variable

$('div').on('click', function(){
    const that = this;
    $(that).text($(that).text() + 1);
    (function(){
       $(that).text($(that).text() + 0)
    })();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>text</div>
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
2

Your problem is that you miss a ; at the end of $('div').text($('div').text() + 1)

Without the ; it is the same as if you would write:

$('div').text($('div').text() + 1)(function(){
   $('div').text($('div').text() + 0)
})();

But because text($('div').text() + 1) does not return a function, you will get this error.

Uncaught TypeError: $(...).text(...) is not a function

This is one situation where you have to use the ; to end your statement.

ecma-262: 11.9.2 Examples of Automatic Semicolon Insertion

The source

a = b + c
(d + e).print()

is not transformed by automatic semicolon insertion, because the parenthesised expression that begins the second line can be interpreted as an argument list for a function call:

a = b + c(d + e).print()

So you have to write:

$('div').text($('div').text() + 1);
(function(){
   $('div').text($('div').text() + 0)
})();
t.niese
  • 39,256
  • 9
  • 74
  • 101
-2

$(document).ready(function(){
$('div').on('click', function(){
 $(this).text($(this).text() + 1);
    var divelement = $(this);
 (function(element){
   element.text($(element).text() + 0);
  })(divelement);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>text</div>
  • This doesn't answer the question and is unnecessary, another answer posted here solves the problem, as well as explains it and was posted earlier. – Walk Oct 07 '17 at 19:06
  • Please check again – MajidAlahevrdi Oct 07 '17 at 19:16
  • Checking again I see variable `element` that is undefined and see no explanation for what you are doing as in [ask]. Code only answers are not very valuable without an explanation – charlietfl Oct 07 '17 at 19:19