For a project I will talk later on, I need to hook the function document.createElement. The code I wanted to write was:
| var original = document.createElement; document.createElement = function (tag) { // Do something return original(tag); }; | 
Problem
However, there's a silly Javascript exception triggered if you try to take a reference of the function
| var createElement = document.createElement; createElement('div'); // TypeError: Illegal Invocation | 
Naive Solution
Since it looks like we cannot use anything else but document.createElement to execute the function, I decided to restore the original document.createElement within the hook function. It is verbose but works.
| var original = document.createElement; var hook = function (tag) { document.createElement = original; // Do something var el = document.createElement(tag); document.createElement = hook; return el; }; document.createElement = hook; | 
Why?
But then, I asked myself, how did they implement a function that could only be called with document.createElement form. Then I remembered that this calling convention sets this to be document. So they must be doing a check like this:
| document.createElement = function () { if (this !== document) { throw new TypeError('Illegal Invocation'); } // ... } | 
Solution
Now that we know that they check for this === document, we can use .call to force it 🙂
| var original = document.createElement; document.createElement = function (tag) { // Do something return original.call(document, tag); }; | 
