1

In an attempt to simplify my question I originally wrote out a question that did in fact work. So let's suppose I have this code which uses D3 inside an ES6 class:

export default class MyClass{
    constructor(){
        this.radius = 1;
    }
    myFunc(){
        this.tooltip //defined elsewhere in the class don't worry about it
            .on('mouseover', function(){
                d3.select(this).transition()
                    .ease('elastic')
                    .duration('250')
                    .attr('r', this.radius*1.5);
                    //keyword this has now been overridden
            });
    }
}

But how can I achieve the above functionality, or should I be taking a different approach?

Alex H Hadik
  • 744
  • 2
  • 7
  • 16

2 Answers2

0

answering the first revision of the question

The this in your event handler is the same as this in the myFunc method, but this has nothing to do with classes. The callback is an arrow function, that's all. (There is no function expression in your code).

But how can I achieve the above functionality, or should I be taking a different approach?

You already are achieving the desired functionality, and no you should not take a different approach.

Community
  • 1
  • 1
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
  • while he is using arrow function everything will be ok, instead of anonymous function in that case he will get `undefined` – The Reason Apr 20 '16 at 12:56
  • 1
    @The: If he had used a function expression instead of the arrow function, `this` would refer to the `#selector` element that jQuery passes into the handler. – Bergi Apr 20 '16 at 13:07
  • probably i made something wrong with my example, but you can check it, when i'm clicking on button i get `undefined`. I know about jQuery that inside event handler `this` references to the element on which it has been fired. [fiddle](https://jsfiddle.net/hxm4smc1/174/) – The Reason Apr 20 '16 at 13:13
  • @The: `this` is the button, `this.myvar` is undefined of course. – Bergi Apr 20 '16 at 13:13
  • @Bergi I'm actually using D3 not Jquery but same difference (see updated question) - but what you are describing is exactly my problem. – Alex H Hadik Apr 20 '16 at 13:16
  • Looking at my code now it appears that its a name collision not a scope problem (?) and so perhaps I simply need to re-assign the `this` that refers to the class. – Alex H Hadik Apr 20 '16 at 13:17
  • Actually that doesn't work as well. Can you explain first why an anonymous function and arrow expression have different behaviors? – Alex H Hadik Apr 20 '16 at 13:23
0

Now, looking at the new question, this still has nothing to do with classes.

But how can I achieve the desired functionality?

You can't have this point to two different things, so you'll have to use a variable for at least one of them. The default var that = this approach still works well:

myFunc(){
    var that = this;
    this.tooltip.on('mouseover', function(e){
         d3.select(this).transition()
            .ease('elastic')
            .duration('250')
            .attr('r', that.radius*1.5);
    });
}

(You can also use var radius = this.radius; if it won't change til the mouseover event).

Or you use event.currentTarget:

myFunc(){
    this.tooltip.on('mouseover', (e) => {
         d3.select(e.currentTarget).transition()
            .ease('elastic')
            .duration('250')
            .attr('r', this.radius*1.5);
    });
}

Or you even combine the two and don't use this at all, as it may be confusing what it does refer to.

Community
  • 1
  • 1
Bergi
  • 513,640
  • 108
  • 821
  • 1,164