7

I have a bootstrap modification for a tooltip. and process my js with webpack/babel

A simplification of my code could be:

    $('[data-toggle="tooltip"]').tooltip({
        title: () => {
            return $(this).children('.tooltip-html-content').html();
        }
    });

This should be the element, bootstrap will call this function with:

   getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      return title
    }

The important line is:

 o.title.call($e[0])

Where $e[0] is the tooltip dom element.

Well, when I process this with babel the result change this by _this a before he assign _this to a value that he consider is the real this.

The question: Can I avoid this conversion in babel for this specific function?

=====

Final solution based in the response:

   getTitle: function getTitle() {
Raúl Martín
  • 4,471
  • 3
  • 23
  • 42
  • 1
    Side note: There's no need for the outermost `()` around your arrow function, `title: () => { /* ... */ }` is fine. – T.J. Crowder Jul 15 '16 at 17:51
  • You should not use an arrow as this is going COMPLETELY against the spec. Soon (or whenever it happens) babel won't need to transpile arrow function anymore and your code will break. Arrow functions are not only a shorthand for function. They have a different semantic. If you don't want that semantic you should not use it in that case. – Hugo Dozois Jul 15 '16 at 18:04
  • Related: [Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?](http://stackoverflow.com/q/34361379/218196) – Felix Kling Jul 17 '16 at 11:44

1 Answers1

18

You've used an arrow function, which by definition closes over the this where it's created.

If you don't want that behavior, don't use an arrow function:

$('[data-toggle="tooltip"]').tooltip({
    title: function() {
    // ----^^^^^^^^^^
        return $(this).children('.tooltip-html-content').html();
    }
});

Re your edit:

I want to use the arrow function. I prefer do a babel exclusion than an eslint exclusion.

You can't, not with that getTitle, since the only way it gives you access to the element is by setting this. Arrow functions by their nature have a fixed this (by not having one at all; they close over the one in the execution context where they were created, which is fixed). You cannot use an arrow function for any function where you want this determined by the caller, such as in this case.

Your choices are either to modify Bootstrap, or use a normal function. The latter seems the more reasonable thing to do.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I enforce my eslint to avoid this function. I want if using this kind of functions I can have the same behaviour. thanks for the response. – Raúl Martín Jul 15 '16 at 17:53
  • @RaúlMartín: I don't understand what you mean by that, other than that you're using ESLint. If you're using jQuery, you need to turn off that ESLint warning about `this` outside constructors, it's not applicable. (I would argue you should turn it of *anyway*, but...) But I don't know what you mean by *"...I want if using this kind of functions I can have the same behaviour. thanks for the response"*. If you mean you want to use an arrow function but have `this` controlled by how the function is called, you can't. That's half the point of arrow functions. – T.J. Crowder Jul 15 '16 at 17:55
  • My configuration it is working fine with Jquery and show the error in the corrects case like this one. – Raúl Martín Jul 15 '16 at 17:56
  • @RaúlMartín: Still not following. You can't use arrow functions for any situation where you need `this` set by how the function is called rather than where it's defined. So you can't use one here. (Well...not reasonably, and possibly not at all, depending on how `tooltip` is implemeneted.) – T.J. Crowder Jul 15 '16 at 17:57
  • @RaúlMartín Using a linter to enforce going against the spec is a very bad idea. – Hugo Dozois Jul 15 '16 at 18:06
  • get_title is part of bootstrap https://github.com/twbs/bootstrap/blob/master/js/tooltip.js#L410 Anyways, Let me time to read more about. If I am against the spec here or not. if it is not more reply I will come back a check a valid reply. And Thanks!!! – Raúl Martín Jul 15 '16 at 18:09
  • @RaúlMartín: Ah, then in that case, you're stuck. You must either 1. Modify Bootstrap, or 2. Use a normal function. I'd go for option 2. – T.J. Crowder Jul 15 '16 at 18:10
  • 1
    @rockerest: Hey, I try to take feedback on board. I was editing right next to it, and... ;-) – T.J. Crowder Jul 15 '16 at 18:15