I could need your help, at the moment I am trying to call a method within a object through a addEventListener activation. The problem is that the this pointer is changing as soon as the method get called. I tried to use the .call to give the method the right context back and it worked as expected but is this the best way ?
<!doctype html>
<html>
<head>
<title>Java Script Test</title>
<meta charset="UTF-8" />
<!-- <script src="//code.jquery.com/jquery-1.11.2.min.js"></script> -->
<script src="../resurces/js/jquery-1.11.2.min.js" ></script>
<script>
var test_class = function(){
this.variable = "more text";
this.click = function(){
$("#return").text("Content: "+this.variable);
}
this.aktivate_listener = function(){
var that = this;
document.getElementById("clicker").addEventListener("click", function(){that.click.call(that)});
}
}
$("document").ready(function(){
console.log("#ready");
var class1 = new test_class();
class1.aktivate_listener();
});
</script>
</head>
<body>
<p id="clicker">This is some Text to click on.</p>
<p id="return"></p>
</body>
</html>
Do some of you know a better way ?
Thanks for your effort ,
Flo
That's mostly fine, but a couple of points:
You don't need to do that.click.call(that) — simply that.click() will work.
You're not passing on the event object that your anonymous function receives. If you don't need it, that's fine, but I thought I'd mention it.
Another alternative is to use Function#bind:
this.aktivate_listener = function(){
document.getElementById("clicker").addEventListener("click", this.click.bind(this));
}
Function#bind returns a function that, when called, turns around and calls the original function with this set to a specific value. So this.click.bind(this) creates a function that, when called, will call click on the object with this referring to the object. Any arguments to the bound function are passed on when it calls the underlying function.
Re your comment:
But I read that you can't remove an EventListener that is created with .bind A problem in the example above is that you cannot remove the listener with bind. That is taken from the Mozilla Developer Network.
If so, MDN is wrong. It's community-edited, that happens. :-)
In terms of being able to remove the handler with removeEventListener, there's no difference at all between your code and using Function#bind as above: You can't remove the listener in either case without changing the code to remember what we passed to addEventListener.
There's nothing special about event handlers that use bind. Just like any other event handler, if you want to remove it with removeEventListener, you have to have a reference to the same function you added when removing it. In your code, that would be the anonymous function that you have wrapped around that.click.call(that);, and since you didn't keep a reference to it, you can't remove it. Similarly, in my code above, you can't remove the listener because I didn't keep a reference to the bound function.
If that's something you need to do, just remember the function you want to remove — that's a reference to your anonymous function, or a reference to the function returned by Function#bind. You might store it on your object, for instance.
this.aktivate_listener = function(){
if (this.boundClick) {
this.deaktivate_listener();
}
this.boundClick = this.click.bind(this);
document.getElementById("clicker").addEventListener("click", this.boundClick);
};
this.deacktivate_listener = function(){
document.getElementById("clicker").removeEventListener("click", this.boundClick);
this.boundClick = null;
};
Looking again at your code, you have a third option: Your click function is a closure over the call to test_class that created the instance, so you don't need to create another closure, just use the one you already have:
var test_class = function(){
// Remember `this` in a variable
var self = this;
this.variable = "more text";
this.click = function(){
// Use it here
$("#return").text("Content: "+self.variable);
};
this.aktivate_listener = function(){
// Just use `this.click` here
document.getElementById("clicker").addEventListener("click", this.click);
};
this.deaktivate_listener = function(){
// Just use `this.click` here
document.getElementById("clicker").removeEventListener("click", this.click);
};
};
Side note: You need a ; at the end of statements like var f = function() { };, because those are statements, not declarations. I've added them above. If you don't provide it, Automatic Semicolon Insertion will add it for you most of the time, but you can trip up if you're not careful.
Examples of all of the above:
Your way without .call (without deaktivate):
var Test = function(id, name) {
this.id = id;
this.name = name;
this.click = function() {
snippet.log("My name is " + this.name);
};
this.aktivate_listener = function() {
var that = this;
document.getElementById(this.id).addEventListener(
"click",
function() { that.click(); },
false
);
};
};
var t1 = new Test("one", "test one");
t1.aktivate_listener();
var t2 = new Test("two", "test two");
t2.aktivate_listener();
<div id="one">Click me (one)</div>
<div id="two">Click me (two)</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
With Function#bind (without deaktivate):
var Test = function(id, name) {
this.id = id;
this.name = name;
this.click = function() {
snippet.log("My name is " + this.name);
};
this.aktivate_listener = function() {
document.getElementById(this.id).addEventListener(
"click",
this.click.bind(this),
false
);
};
};
var t1 = new Test("one", "test one");
t1.aktivate_listener();
var t2 = new Test("two", "test two");
t2.aktivate_listener();
<div id="one">Click me (one)</div>
<div id="two">Click me (two)</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Using the existing closure (without deaktivate):
var Test = function(id, name) {
var self = this;
this.id = id;
this.name = name;
this.click = function() {
snippet.log("My name is " + self.name);
};
this.aktivate_listener = function() {
document.getElementById(this.id).addEventListener(
"click",
this.click,
false
);
};
};
var t1 = new Test("one", "test one");
t1.aktivate_listener();
var t2 = new Test("two", "test two");
t2.aktivate_listener();
<div id="one">Click me (one)</div>
<div id="two">Click me (two)</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Your way without .call (with deaktivate):
var Test = function(id, name) {
this.id = id;
this.name = name;
this.counter = 0;
this.click = function() {
snippet.log("My name is " + this.name);
if (++this.counter == 2) {
this.deaktivate_listener();
};
};
this.aktivate_listener = function() {
var that = this;
if (this.boundClick) {
this.deaktivate_listener();
}
this.boundClick = function() { that.click(); };
document.getElementById(this.id).addEventListener(
"click",
this.boundClick,
false
);
};
this.deaktivate_listener = function() {
if (this.boundClick) {
document.getElementById(this.id).removeEventListener(
"click",
this.boundClick,
false
);
this.boundClick = null;
}
};
};
var t1 = new Test("one", "test one");
t1.aktivate_listener();
var t2 = new Test("two", "test two");
t2.aktivate_listener();
<div id="one">Click me (one) (second click deactivates)</div>
<div id="two">Click me (two) (second click deactivates)</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
With Function#bind (with deaktivate):
var Test = function(id, name) {
this.id = id;
this.name = name;
this.counter = 0;
this.click = function() {
snippet.log("My name is " + this.name);
if (++this.counter == 2) {
this.deaktivate_listener();
};
};
this.aktivate_listener = function() {
if (this.boundClick) {
this.deaktivate_listener();
}
this.boundClick = this.click.bind(this);
document.getElementById(this.id).addEventListener(
"click",
this.boundClick,
false
);
};
this.deaktivate_listener = function() {
if (this.boundClick) {
document.getElementById(this.id).removeEventListener(
"click",
this.boundClick,
false
);
this.boundClick = null;
}
};
};
var t1 = new Test("one", "test one");
t1.aktivate_listener();
var t2 = new Test("two", "test two");
t2.aktivate_listener();
<div id="one">Click me (one) (second click deactivates)</div>
<div id="two">Click me (two) (second click deactivates)</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Using the existing closure (with deaktivate):
var Test = function(id, name) {
var self = this;
this.id = id;
this.name = name;
this.counter = 0;
this.click = function() {
snippet.log("My name is " + self.name);
if (++self.counter == 2) {
self.deaktivate_listener();
};
};
this.aktivate_listener = function() {
document.getElementById(this.id).addEventListener(
"click",
this.click,
false
);
};
this.deaktivate_listener = function() {
document.getElementById(this.id).removeEventListener(
"click",
this.click,
false
);
};
};
var t1 = new Test("one", "test one");
t1.aktivate_listener();
var t2 = new Test("two", "test two");
t2.aktivate_listener();
<div id="one">Click me (one) (second click deactivates)</div>
<div id="two">Click me (two) (second click deactivates)</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Here is the version I use at the moment, it is made of #T.J. Crowder answers.
function boxOperator(){
this.event = [];
this.addEvent = function(element, event, tocall_function, arg){
var call_function = tocall_function.bind(this, arg);
this.event[this.event.length] = {
"element" : element,
"event" : event,
"call_function" : call_function
};
document.getElementById(element).addEventListener(event,call_function);
};
this.removeEvent = function(element, event){
if(!element){return false;};
var remove_entry = function(index, array){return array.slice(0,index-1).concat(array.slice(index+1));}
for(var i = 0; i < this.event.length;i++){
if(this.event[i].element == element){
var entry = this.event[i];
if(entry.event == event){
document.getElementById(entry.element).removeEventListener(entry.event,entry.call_function);
this.event = remove_entry(i, this.event);
}
if(typeof event == "undefined"){
document.getElementById(entry.element).removeEventListener(entry.event,entry.call_function);
this.event = remove_entry(i, this.event);
}
}
}
};
}
Related
I have created a basic plugin template based on the code generated here:
http://starter.pixelgraphics.us/
Here is a link to the very basic skeleton:
https://jsbin.com/yatofefade/edit?html,js,console,output
$.curationPanel = function( el, options ) {
var base = this;
base.$el = $(el);
base.el = el;
base.$el.data( "curationPanel", base );
base.init = function( ) {
base.options =
$.extend( {}, $.curationPanel.defaultOptions, options );
};
base.runMe = function( ) {
alert( "I've Been Run" );
};
base.init( );
};
$.curationPanel.defaultOptions = { };
$.fn.curationPanel = function( options ) {
return this.each( function( ) {
(new $.curationPanel( this, options ));
});
};
$(".curationPanel").each( function( i, val ) {
var cp = $(this).curationPanel({});
cp.runMe( );
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="curationPanel">INSIDE THE PANEL<div class="curationErrors"></div></div>
</body>
</html>
My question is, why do I get an error when trying to call runMe( ) on a created instance of curationPanel? What is the correct way to create callable public functions within the plugin?
In your case cp is a jQuery object, not an instance of the curationPanel since you are returning this from the plugin method, that is why the error.
There are multiple ways to do this.
One way is to break the chaining nature of the jQuery and return an instance of the plugin object as shown below. Other than breaking the chaining nature of jQuery method, another drawback of this design is, at any call you can use this to initialize the plugin for only one element, ie if you have a selector which selects more than 1 element and then call the plugin, the plugin will be initialized for only the first element.
$.curationPanel = function(el, options) {
var base = this;
base.$el = $(el);
base.el = el;
base.$el.data("curationPanel", base);
base.init = function() {
base.options = $.extend({}, $.curationPanel.defaultOptions, options);
};
base.runMe = function() {
snippet.log("I've Been Run");
};
base.init();
};
$.curationPanel.defaultOptions = {};
$.fn.curationPanel = function(options) {
return new $.curationPanel(this[0], options);
};
$(".curationPanel").each(function(i, val) {
var cp = $(this).curationPanel({});
cp.runMe();
});
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="curationPanel">INSIDE THE PANEL
<div class="curationErrors"></div>
</div>
Another way is to obtain the plugin instance using the data api like
$.curationPanel = function(el, options) {
var base = this;
base.$el = $(el);
base.el = el;
base.$el.data("curationPanel", base);
base.init = function() {
base.options = $.extend({}, $.curationPanel.defaultOptions, options);
};
base.runMe = function() {
snippet.log("I've Been Run");
};
base.init();
};
$.curationPanel.defaultOptions = {};
$.fn.curationPanel = function(options) {
return this.each(function() {
(new $.curationPanel(this, options));
});
};
$(".curationPanel").each(function(i, val) {
var cp = $(this).curationPanel({});
$(this).data('curationPanel').runMe();
});
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="curationPanel">INSIDE THE PANEL
<div class="curationErrors"></div>
</div>
I have a function that returns something into the dom (a cellrenderer in ag-grid). Is it possible to create two different elements with document.createElement(), attach event listeners with addEventListener(), and return them in a single function?
For instance, this works, but I need to return two elements:
function() {
var el = document.createElement('input');
el.addEventListener('click', function () {
console.log("el clicked");
});
return el;
}
//returns <input/> into the dom, and attaches eventlistener
Here is what I'm trying to do. The only way I have been able to get it to return html is by adding outerHTML methods on the return, but it doesn't seem to add the event listeners that way. If you take off .outerHTML it will return [object HTMLInputElement][object HTMLButtonElement]
function() {
var el = document.createElement('input');
var el2 = document.createElement('button');
el.addEventListener('click', function () {
console.log("el clicked");
});
el2.addEventListener('click', function () {
console.log("el2 clicked");
});
return el.outerHTML + el2.outerHTML
}
//want this to return <input/><button/> with eventlisteners attached
It is because the events are attached to the dom element, when you get the html markup of those elements the attached handlers are lost.
You can return a DocumentFragment which contains both the elements like
function x() {
var el1 = document.createElement('input');
var el2 = document.createElement('button');
el2.innerText = 'Button';
el1.addEventListener('click', function() {
snippet.log("el1 clicked");
});
el2.addEventListener('click', function() {
snippet.log("el2 clicked");
});
var fragment = document.createDocumentFragment();
fragment.appendChild(el1);
fragment.appendChild(el2);
return fragment;
}
document.body.appendChild(x())
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
If you want to return the html, then you can use the onclick attribute like
function x() {
var el1 = document.createElement('input');
var el2 = document.createElement('button');
el2.innerText = 'Button';
el1.setAttribute('onclick', 'el1click()');
el2.setAttribute('onclick', 'el2click()');
return el1.outerHTML + el2.outerHTML
}
function el1click() {
snippet.log("el1 clicked");
}
function el2click() {
snippet.log("el2 clicked");
}
ct.innerHTML = x();
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<div id="ct"></div>
I have a class (I think this is called) and created an object called peter in my code. I now want to level up Peter as follows:
// Define the class
function character(name, level){
this.name = name;
this.level = level;
}
// Create Peter at level 1
var peter = new character("Peter", 1);
// This will display the name of the character, level and a button to level him up
character.prototype.display = function() {
document.getElementById("name").innerHTML += this.name;
document.getElementById("level").innerHTML += this.level;
// This line calls `levelup()` on load which is not what I want
// and clicking the button no more calls `levelup`!
document.getElementById("levelupbutton").onclick = this.levelup();
// This line would call the function on click, but it looks like `this`
// is not being passed down to the function `levelup` so I get NaN on
// this.level down below?
//document.getElementById("levelupbutton").onclick = this.levelup;
};
character.prototype.levelup = function() {
alert("Level up in progress!");
this.level++;
alert(this.level);
}
peter.display();
jsfilldle
I'm probably incorrectly calling the function and I can't seem to figure out how to do it correctly. Can anyone give me some pointers? I'm new to OOP, so if the solution involves something OOP, could you please try to explain it as much as possible?
You need to bind this to levelup and not call it in line to get your desired behavior. Updated your fiddle with the correct answer.
levelupbutton.onclick = this.levelup.bind(this);
function character(name, level){
this.name = name;
this.level = level;
}
var peter = new character("Peter", 1); // Instantiate new objects with 'new'
character.prototype.display = function(){
document.getElementById("name").innerHTML += this.name;
document.getElementById("level").innerHTML += this.level;
document.getElementById("levelupbutton").onclick = this.levelup.bind(this);
};
character.prototype.levelup = function(){
alert("Level up in progress!");
this.level++;
alert(this.level);
}
peter.display();
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>
When attaching a handler function to an element, the value of this inside of the handler is a reference to the element. It is the same as the value of the e.target property of the event argument that is passed to the handler.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#The_value_of_this_within_the_handler
You could use Function.prototype.bind() method which will create a new function that will have its this set to the provided value.
Just attach the click handler like this:
document.getElementById("levelupbutton").addEventListener('click',
this.levelup.bind(this)
);
Why use addEventListener?
addEventListener is the way to register an event listener as
specified in W3C DOM..
Fiddle: http://jsfiddle.net/abhitalks/sjfxorxz/6/
Snippet:
function character(name, level) {
this.name = name;
this.level = level;
}
character.prototype.levelup = function() {
this.level++;
document.getElementById("level").innerHTML += this.level;
}
character.prototype.display = function() {
document.getElementById("name").innerHTML += this.name;
document.getElementById("level").innerHTML += this.level;
document.getElementById("levelupbutton").addEventListener('click',
this.levelup.bind(this)
);
}
var peter = new character("Peter", 1);
peter.display();
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>
Alternatively, you could also save the reference and use that inside an anonymous function call instead of inlining it.
For example:
character.prototype.display = function() {
var self = this;
document.getElementById("levelupbutton").addEventListener('click',
function () {
self.levelup();
});
}
Fiddle 2: http://jsfiddle.net/abhitalks/sjfxorxz/9/
Snippet 2:
function character(name, level) {
this.name = name;
this.level = level;
}
character.prototype.levelup = function() {
this.level++;
document.getElementById("level").innerHTML += this.level;
}
character.prototype.display = function() {
var self = this;
document.getElementById("name").innerHTML += this.name;
document.getElementById("level").innerHTML += this.level;
document.getElementById("levelupbutton").addEventListener('click',
function () {
self.levelup();
});
}
var peter = new character("Peter", 1);
peter.display();
<span>Character Name:</span> <span id="name"></span><br />
<span>Character Level:</span> <span id="level"></span><br />
<button id="levelupbutton">Level Up!</button>
I have code like below. I made Javascript class named "Car" and in constructor I add event to html "" tag. But this event can't fire.
Could somebody help me?
Thanks,
A.
function Car(model, brand) {
this.model = model;
this.brand = brand;
document.getElementById('button').addEventListener('onclick', this.info);
}
// method
Car.prototype.info = function() {
alert("It is " + this.model);
};
// define cariable
var car = new Car("RX7", "Mazda");
// Invoke method in html
//car.info();
// second way
window.onload = function() {
var car = new Car("RX7", "Mazda");
};
<button id="button">Click me</button>
The event should be click not onclick.
To bind the context use bind(this) on the event handler function reference.
function Car(model, brand) {
this.model = model;
this.brand = brand;
document.getElementById('button').addEventListener('click', this.info.bind(this));
// ^^^^^^^ ^^^^^^^^^^
}
// method
Car.prototype.info = function() {
alert("It is " + this.model);
};
// define cariable
var car = new Car("RX7", "Mazda");
// Invoke method in html
//car.info();
// second way
window.onload = function() {
var car = new Car("RX7", "Mazda");
};
<button id="button">Click me</button>
I hope this is just for the Demo purpose, if you want to use this in real project use following code.
function Car(model, brand) {
this.model = model;
this.brand = brand;
}
// method
Car.prototype.info = function() {
alert("It is " + this.model);
};
// define cariable
var car = new Car("RX7", "Mazda");
document.addEventListener('DOMContentLoaded', function() {
var car = new Car("RX7", "Mazda");
document.getElementById('button').addEventListener('click', car.info.bind(car));
});
<button id="button">Click</button>
#Tushar
Thank You very much. I wouldn't do this wihtout your help :-)
For someone, who wants have everything "more inside" a class, I prepared some changes in #Tushar code.
But I don't know if it is consistent in any programming standard.
function Car(model, brand) {
this.model = model;
this.brand = brand;
document.getElementById('button').addEventListener('click', this.info.bind(this));
}
// method
Car.prototype.info = function() {
alert("It is " + this.model);
};
document.addEventListener('DOMContentLoaded', function() {
var car = new Car("RX7", "Mazda");
});
<button id="button">Click</button>
Is there a best-practice or common way in JavaScript to have class members as event handlers?
Consider the following simple example:
<head>
<script language="javascript" type="text/javascript">
ClickCounter = function(buttonId) {
this._clickCount = 0;
document.getElementById(buttonId).onclick = this.buttonClicked;
}
ClickCounter.prototype = {
buttonClicked: function() {
this._clickCount++;
alert('the button was clicked ' + this._clickCount + ' times');
}
}
</script>
</head>
<body>
<input type="button" id="btn1" value="Click me" />
<script language="javascript" type="text/javascript">
var btn1counter = new ClickCounter('btn1');
</script>
</body>
The event handler buttonClicked gets called, but the _clickCount member is inaccessible, or this points to some other object.
Any good tips/articles/resources about this kind of problems?
ClickCounter = function(buttonId) {
this._clickCount = 0;
var that = this;
document.getElementById(buttonId).onclick = function(){ that.buttonClicked() };
}
ClickCounter.prototype = {
buttonClicked: function() {
this._clickCount++;
alert('the button was clicked ' + this._clickCount + ' times');
}
}
EDIT almost 10 years later, with ES6, arrow functions and class properties
class ClickCounter {
count = 0;
constructor( buttonId ){
document.getElementById(buttonId)
.addEventListener( "click", this.buttonClicked );
}
buttonClicked = e => {
this.count += 1;
console.log(`clicked ${this.count} times`);
}
}
https://codepen.io/anon/pen/zaYvqq
I don't know why Function.prototype.bind wasn't mentioned here yet. So I'll just leave this here ;)
ClickCounter = function(buttonId) {
this._clickCount = 0;
document.getElementById(buttonId).onclick = this.buttonClicked.bind(this);
}
ClickCounter.prototype = {
buttonClicked: function() {
this._clickCount++;
alert('the button was clicked ' + this._clickCount + ' times');
}
}
A function attached directly to the onclick property will have the execution context's this property pointing at the element.
When you need to an element event to run against a specific instance of an object (a la a delegate in .NET) then you'll need a closure:-
function MyClass() {this.count = 0;}
MyClass.prototype.onclickHandler = function(target)
{
// use target when you need values from the object that had the handler attached
this.count++;
}
MyClass.prototype.attachOnclick = function(elem)
{
var self = this;
elem.onclick = function() {self.onclickHandler(this); }
elem = null; //prevents memleak
}
var o = new MyClass();
o.attachOnclick(document.getElementById('divThing'))
You can use fat-arrow syntax, which binds to the lexical scope of the function
function doIt() {
this.f = () => {
console.log("f called ok");
this.g();
}
this.g = () => {
console.log("g called ok");
}
}
After that you can try
var n = new doIt();
setTimeout(n.f,1000);
You can try it on babel or if your browser supports ES6 on jsFiddle.
Unfortunately the ES6 Class -syntax does not seem to allow creating function lexically binded to this. I personally think it might as well do that. EDIT: There seems to be experimental ES7 feature to allow it.
I like to use unnamed functions, just implemented a navigation Class which handles this correctly:
this.navToggle.addEventListener('click', () => this.toggleNav() );
then this.toggleNav() can be just a function in the Class.
I know I used to call a named function but it can be any code you put in between like this :
this.navToggle.addEventListener('click', () => { [any code] } );
Because of the arrow you pass the this instance and can use it there.
Pawel had a little different convention but I think its better to use functions because the naming conventions for Classes and Methods in it is the way to go :-)