13

When I attempt to use Object destructuring with ev.preventDefault(), I receive the following error in Chrome:

Uncaught TypeError: Illegal invocation

However, when I use ev.preventDefault() without destructuring, it works fine. Code that reproduces this issue is shown below.

const button = document.getElementById(`test-button`);

button.onclick = ({ preventDefault }) => {
  preventDefault();
};
<button id=test-button type=button>Click me to see the error</button>

Any idea why this is happening? Or how I can use Object destructuring with the Event Object?

dwhieb
  • 1,706
  • 19
  • 29
  • You don't need the Event Object when destructuring? – zer00ne Apr 02 '18 at 18:03
  • Well, it's a method like any other, it must be called on the appropriate target (the event object) to know which default to prevent. – Bergi Apr 02 '18 at 18:05
  • @zer00ne, @Bergi The `({ preventDefault })` in the function parameters is the Event Object. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Unpacking_fields_from_objects_passed_as_function_parameter for more examples of destructuring function parameters. – dwhieb Apr 02 '18 at 18:09
  • @dwhieb Yes. And when you do `preventDefault()`, that's not [method call syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) and the event object is nowhere to be found: *Illegal invocation*. – Bergi Apr 02 '18 at 18:11
  • @Bergi Interesting - I didn't realize destructuring doesn't bind its context. If you put that in an answer I'll mark it as the accepted answer. Thanks! – dwhieb Apr 02 '18 at 18:17

1 Answers1

19

preventDefault is a method that must be invoked on an event object to know which default to prevent. When you do just preventDefault(), that's not method call syntax and the event object is nowhere to be found: Illegal invocation. Destructuring syntax just accesses the value, it does not automatically bind any functions.

button.onclick = (e) => {
  const { preventDefault } = e; // like const preventDefault = e.preventDefault;
  preventDefault(); // does not work, unlike preventDefalt.call(e)
};
Przemysław Zalewski
  • 3,836
  • 1
  • 23
  • 23
Bergi
  • 630,263
  • 148
  • 957
  • 1,375