120

例如,如果我这样做:

var q = document.querySelectorAll;

q('body');

我在 Chrome 中收到“非法调用”错误。我想不出任何理由为什么这是必要的。一方面,并​​非所有本机代码功能都如此。事实上我可以这样做:

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

var x = new o();

一切正常。特别是我在处理文档和控制台时发现了这个问题。有什么想法吗?

4

3 回答 3

194

这是因为您丢失了函数的“上下文”。

你打电话时:

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);
}
于 2012-05-24T18:53:29.630 回答
-1

在我的情况下,由于将未声明的变量作为参数传递而发生非法调用。确保在传递给函数之前声明变量。

于 2017-08-07T12:12:49.560 回答
-1

你可以这样使用:

let qsa = document.querySelectorAll;
qsa.apply(document,['body']);
于 2018-05-08T03:42:31.357 回答