web-dev-qa-db-ja.com

JavaScriptで特定の関数呼び出しが「不正な呼び出し」と呼ばれるのはなぜですか?

たとえば、これを行う場合:

var q = document.querySelectorAll;

q('body');

Chromeで「不正な呼び出し」エラーが表示されます。これが必要な理由は考えられません。 1つは、すべてのネイティブコード関数の場合ではありません。実際、私はこれを行うことができます:

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

var x = new o();

そして、すべてがうまく機能します。特に、ドキュメントとコンソールを扱うときにこの問題を発見しました。何かご意見は?

78
user1152187

これは、関数の「コンテキスト」を失ったためです。

電話するとき:

document.querySelectorAll()

関数のコンテキストはdocumentであり、そのメソッドの実装によりthisとしてアクセスできます。

単にqを呼び出すと、コンテキストはなくなります-代わりに「グローバル」なwindowオブジェクトになります。

querySelectorAllの実装はthisを使用しようとしますが、DOM要素ではなく、Windowオブジェクトです。実装はWindowオブジェクト上に存在しないDOM要素のメソッドを呼び出そうとし、インタープリターは当然ながらファウルを呼び出します。

これを解決するには、新しいバージョンのJavascriptで.bindを使用します。

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

これにより、以降のqのすべての呼び出しに正しいコンテキストが保証されます。 .bindがない場合は、これを使用します:

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

次のように使用できます:

let qsa = document.querySelectorAll;
qsa.apply(document,['body']);
0
love-for-coding