For example, if I do this:
var q = document.querySelectorAll;
q('body');
I get an "Illegal invocation" error in Chrome. I can't think of any reason why this is necessary. For one, it's not the case with all native code functions. In fact I can do this:
var o = Object; // which is a native code function
var x = new o();
And everything works just fine. In particular I've discovered this problem when dealing with document and console. Any thoughts?
It's because you've lost the "context" of the function.
When you call:
document.querySelectorAll()
the context of the function is document
, and will be accessible as this
by the implementation of that method.
When you just call q
there's no longer a context - it's the "global" window
object instead.
The implementation of querySelectorAll
tries to use this
but it's no longer a DOM element, it's a Window
object. The implementation tries to call some method of a DOM element that doesn't exist on a Window
object and the interpreter unsurprisingly calls foul.
To resolve this, use .bind
in newer versions of Javascript:
var q = document.querySelectorAll.bind(document);
which will ensure that all subsequent invocations of q
have the right context. If you haven't got .bind
, use this:
function q() {
return document.querySelectorAll.apply(document, arguments);
}