DR01D
DR01D

Reputation: 1365

Can a callback function be an object that stores properties within itself?

The following test code works properly. A mousemove event triggers the checkPosition function which stores the mouse position inside the object mousePosition.

"use strict";

const mousePosition = {
    x: 0,
    y: 0
}

function checkPosition(e) {
    mousePosition.x = e.clientX;
    mousePosition.y = e.clientY;
}
    
addEventListener("mousemove", checkPosition);
addEventListener("click", () => console.log(mousePosition) );

However I'd like to simplify this if possible. Is there a way to store the mouse position inside of the callback function? I've tried this a bunch of different ways and I'm having no luck.

The code below doesn't work but hopefully it shows what I'm trying to accomplish. I know my syntax must be screwed up but I don't know how to construct this. Thanks so much!

"use strict";

const mousePosition = (e) => {
    x: e.clientX,
    y: e.clientY
};
    
addEventListener("mousemove", mousePosition);
addEventListener("click", () => console.log(mousePosition.x, mousePosition.y) );

Upvotes: 3

Views: 67

Answers (2)

Alnitak
Alnitak

Reputation: 339816

You can use a named function to provide access to the function's own object:

"use strict";

const mousePosition = function f(e) {
  f.x = e.clientX;
  f.y = e.clientY;
};

addEventListener("mousemove", mousePosition);
addEventListener("click", () => console.log(mousePosition.x, mousePosition.y));

The use of the function's local name f internally within the mousePosition function is necessary to ensure that the properties get stored on the given function, regardless of whether some other piece of code replaces the external variable mouseFunction with something else.

[notwithstanding that const should prevent that, it's still not good practise to refer to an object's external name from within that object]

In pre-ES5 code you could have used arguments.callee.<property> but strict mode prohibits that.

Upvotes: 1

Racil Hilan
Racil Hilan

Reputation: 25351

You can do it by adding the x and y properties dynamically like this:

"use strict";

const mousePosition = (e) => {
  mousePosition.x = e.clientX;
  mousePosition.y = e.clientY;
};

addEventListener("mousemove", mousePosition);
addEventListener("click", () => console.log(mousePosition.x, mousePosition.y));

Upvotes: 4

Related Questions