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

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

var q = document.querySelectorAll;

q('body');

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

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

var x = new o();

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

3 ответа

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

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

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);
}

Вы можете использовать так:

let qsa = document.querySelectorAll;
qsa.apply(document,['body']);

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

Еще одно лаконичное решение:

const q=s=>document.querySelectorAll(s);
q('body');
Другие вопросы по тегам