0

I wrote this simple code to remove all text inside of a h2 element:

const h2 = document.querySelector('h2');
const children = Array.from(h2.childNodes)
                      .filter((childNode)=>childNode.nodeName === '#text');
children.forEach(h2.removeChild); // Throws TypeError: Illegal invocation

However, the last line threw an error - TypeError: Illegal invocation. This was fixed when I replaced the last line with:

children.forEach((child)=>h2.removeChild(child)); // Just works

My question is, why did javascript throw the error in the first place and why did the arrow function fix it? h2.removeChild is a function that takes 1 argument, so shouldn't ( h2.removeChild ) act identically to ( (child)=>h2.removeChild(child) ) ?

keithlee96
  • 1,724
  • 2
  • 11
  • 17

1 Answers1

1

Because you are losing the correct context of .removeChild function here.
You could also do this:

children.forEach(h2.removeChild.bind(h2));
Bsalex
  • 2,847
  • 1
  • 15
  • 22
  • Ok, just tried it, just curious, why is 'this' undefined in a forEach? – keithlee96 Feb 08 '18 at 10:35
  • It is not `undefined`, it is `window`. – Bsalex Feb 08 '18 at 10:41
  • @Bsalex — Only if you've failed to enable strict mode. – Quentin Feb 08 '18 at 10:51
  • @Quentin, Yes, you are right. Good point. – Bsalex Feb 08 '18 at 10:53
  • Why does (child)=>h2.removeChild(child) save the context? It is defined in the same lexical location, so why does making it an arrow function change the context of the function call? – keithlee96 Feb 08 '18 at 10:54
  • @keithlee96 — The value of `this` for non-arrow functions depends on how they are called. Passing `h2.removeChild` as an argument does so without passing the context of `h2` – Quentin Feb 08 '18 at 10:56
  • @Quentin Hmm, thanks. Is there somewhere I can find the documentation that says that node.removeChild must be called with it's 'this' value bound to itself? – keithlee96 Feb 08 '18 at 11:00
  • 1
    [mdn says](https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild) "node is the parent node of child" – Quentin Feb 08 '18 at 11:04
  • Last question, why does the Array.prototype.forEach() function bind the value of 'this' in the callback function to the (Window object / undefined)? – keithlee96 Feb 08 '18 at 11:07