Почему определенные вызовы функций называются "незаконными вызовами" в JavaScript?

Например, если я это сделаю:

var q = document.querySelectorAll;

q('body');

Я получаю сообщение об ошибке "Незаконное обращение" в Chrome. Я не могу придумать, почему это необходимо. Во-первых, это не относится ко всем функциям собственного кода. На самом деле я могу это сделать:

var o = Object; // which is a native code function

var x = new o();

И все работает отлично. В частности, я обнаружил эту проблему при работе с документом и консолью. Любые мысли?

Ответ 1

Это потому, что вы потеряли "контекст" функции.

Когда вы вызываете:

document.querySelectorAll()

контекст функции document и будет доступен как this путем реализации этого метода.

Когда вы просто вызываете q, здесь больше нет контекста - вместо этого это "глобальный" window объект.

Реализация querySelectorAll пытается использовать this, но это уже не элемент DOM, это объект window. Реализация пытается вызвать некоторый метод элемента DOM, который не существует в объекте window, и интерпретатор неудивительно называет фол.

Чтобы решить эту проблему, используйте .bind в новых версиях Javascript:

var q = document.querySelectorAll.bind(document);

который гарантирует, что все последующие вызовы q имеют правильный контекст. Если у вас нет .bind, используйте это:

function q() {
    return document.querySelectorAll.apply(document, arguments);
}

Ответ 2

В моем случае нелегальный вызов произошел из-за передачи необъявленной переменной для функции в качестве аргумента. Обязательно объявляйте переменную перед передачей функции.