2011-09-07 8 views
8

"call"関数を汎用レベルでオーバーライドすることができます。そのため、メソッドがアプリケーションのどこでも呼び出されるたびに何かが発生します。"コール"機能を無効にすることはできますか?

私はObject.callをオーバーライドしようとしましたが、私はそれをやっていましたが、私のアプリの仕方に何も変わっていませんでした。

ところで、私が明示的に "foo.call(this、args)"を呼び出すか、通常の関数呼び出しでも "foo(args)"が動作するはずです。

+0

「Function.call」を考えていますか? 'Object.prototype'に' call'メソッドはありません。 –

+0

おそらくあなたが達成しようとしていることを説明することができます。私はあなたがjavascriptレベルですべてのjavascript関数呼び出しをインターセプトできるとは思わない。おそらくJSエンジンのフックにアクセスする必要があります。 – jfriend00

答えて

8

が鳴る....

JavaScriptは、ECMAScriptの方言として、呼び出し可能オブジェクトの概念を持っています。すべての呼び出し可能オブジェクトは内部プロパティと呼ばれ、[[Call]]と呼ばれます。この特性は、ECMA-262仕様第5版の8.6.2項、表9に記載されています。それは言う:

オブジェクトに関連付けられたコードを実行します。関数呼び出し式を介して呼び出されます。 SpecOpへの引数は、このオブジェクトと、関数呼び出し式に渡される引数を含むリストです。この内部メソッドを実装するオブジェクトは呼び出し可能です。ホストオブジェクトである呼び出し可能オブジェクトだけが参照値を返すことがあります。

内部プロパティに名前がないとのECMAScript言語演算子を経由して直接アクセスすることはできません。

は、しかし、注意すべき事は[[Call]]が仕様が言うれる内部プロパティは、ということです。内部特性は、純粋に仕様目的のために存在します。

したがって、独自のJavaScriptコードでこのメカニズムを使用することはできません。

今そこにFunction.prototypeapplycallで定義された 2つの方法です。 Function.prototype.callの定義を変更した場合、独自の関数fを作成した場合、f.callは実際に(fのプロトタイプまたはf自身でオーバーライドされない限り)そのコードを実行することは確かです。これは、あなたが推測したように、fを直接呼び出すことによって自動的には発生しません。明示的にcallメソッドを呼び出さなければなりません。

すべてのことは、組み込みオブジェクトのプロトタイプであらかじめ定義された標準的なメソッドを使用しないことをお勧めします。ライブラリとアプリケーションの多くの既存コードはFunction.prototype.callに依存しています。それを台無しにしないでください。もちろん、さまざまな方法で一種のAOP動作を実装することができます。 1つはFunction.prototypeに他の方法であるを追加することですが、のいずれかを追加しないでください。別の方法として、前後のフックで独自の呼び出しメソッドを記述する方法があります。

function call(theThis, before, main, after, beforeArgs, mainArgs, afterArgs) { 
    before.apply(theThis, beforeArgs); 
    main.apply(theThis, mainArgs); 
    after.apply(theThis. afterArgs); 
} 
+0

私はいつも元の呼び出し関数のコピーをキャッシュし、最後に呼び出します – user802232

0

つまり、アプリケーションで行われた関数呼び出しをインターセプトしたいとしますか?少なくとも一般的なレベルではない、それをする方法はありません。あなたがここにアスペクト指向プログラミングのいくつかの種類をしたいよう

関連する問題