为什么某些函数调用在 JavaScript 中被称为“非法调用”?

例如,如果我这样做:

var q = document.querySelectorAll;


q('body');

我在 Chrome 中得到一个“非法调用”错误。我想不出有什么必要。首先,并非所有本机代码函数都是这种情况。事实上,我可以这样做:

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


var x = new o();

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

64244 次浏览

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

当你打电话时:

document.querySelectorAll()

函数的上下文是 document,通过该方法的实现可以作为 this访问。

当您只调用 q时,就不再有上下文-而是“全局”window对象。

querySelectorAll的实现尝试使用 this,但它不再是一个 DOM 元素,而是一个 Window对象。这个实现尝试调用一个在 Window对象上不存在的 DOM 元素的某个方法,解释器不出所料地调用了碰撞。

To resolve this, use .bind in newer versions of 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']);