[解決済み] 関数がコンストラクタとして呼び出されているかどうかを検出するには?
質問
ある関数が与えられた。
function x(arg) { return 30; }
呼び方は2通りあります。
result = x(4);
result = new x(4);
前者は30を返し、後者はオブジェクトを返します。
関数がどちらの方法で呼ばれたかを検出するにはどうしたらよいでしょうか 関数自体の内部で ?
あなたの解決策が何であれ、それは次の呼び出しでも同様に動作しなければなりません。
var Z = new x();
Z.lolol = x;
Z.lolol();
現在、すべてのソリューションが
Z.lolol()
がコンストラクタとしてそれを呼び出していると考えています。
どのように解決するのですか?
注意:ES2015以降で可能になりました。参照 Daniel Weinerの回答 .
私は、あなたが望むことが[ES2015より前に]可能であるとは思いません。単に、信頼できる推論を行うために関数内で利用可能な十分な情報がありません。
ECMAScript第3版の仕様を見ると、以下のような手順で
new x()
が呼び出されたときに行われるステップは、基本的に
- 新しいオブジェクトを作成する
-
のprototypeプロパティにその内部[[Prototype]]プロパティを割り当てます。
x
-
呼び出す
x
を通常通り呼び出し、新しいオブジェクトをthis
-
への呼び出しが
x
がオブジェクトを返した場合はそれを返し、そうでない場合は新しいオブジェクトを返します。
関数がどのように呼び出されたかについて、実行中のコードでは何も役に立ちませんので、内部でテストできるのは
x
の中でテストできるのは
this
の値であり、ここでの回答はすべてそうなっています。あなたが観察したように、新しいインスタンス*である
x
を呼び出すと
x
をコンストラクタとして呼び出した場合、既存の
x
として渡される
this
を呼び出したとき
x
を関数として呼び出す場合。
でない限り
によって作られたすべての新しいオブジェクトにプロパティを割り当てます。
x
によって作られるすべての新しいオブジェクトにプロパティを割り当てます。
function x(y) {
var isConstructor = false;
if (this instanceof x // <- You could use arguments.callee instead of x here,
// except in in EcmaScript 5 strict mode.
&& !this.__previouslyConstructedByX) {
isConstructor = true;
this.__previouslyConstructedByX = true;
}
alert(isConstructor);
}
によって構築されたすべてのオブジェクトに余計なプロパティがついてしまうので、これは明らかに理想的ではありません。
x
によって構築されたすべてのオブジェクトに、上書きされる可能性のある無用なプロパティが追加されることになるので、これは明らかに理想的ではありませんが、私はこれがあなたができる最善の方法だと思います。
(*)
のインスタンスというのは不正確な表現ですが、十分に近いですし、
関連
-
[解決済み] 要素外でのクリックを検出するにはどうすればよいですか?
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] jQueryで要素が非表示になっているかどうかを確認するには?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] Java で、あるコンストラクタを別のコンストラクタから呼び出すにはどうすればよいですか?
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み] ジェスト あるクラスの特定のメソッドをモックする方法
-
[解決済み] モバイルWeb HTML5フレームワークの選び方【終了しました
-
[解決済み] CORS: 認証モードは 'include' です。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 配列からオブジェクトを生成する
-
[解決済み] 上級者向けJavaScript。この関数はなぜ括弧でくくられるのですか?重複
-
[解決済み] <Enter>でjQuery UIダイアログを送信する
-
[解決済み] なぜJavaScriptでは!{}[true]がtrueに評価されるのですか?
-
[解決済み] なぜ "use strict "はパフォーマンスを10倍向上させるのか?
-
[解決済み] node.jsで文字列のsha1ハッシュを取得するにはどうすればよいですか?
-
[解決済み] BlobからArrayBufferへ移行する方法
-
[解決済み] JavaScriptでjson-objectのキーを取得する [重複].
-
[解決済み] JavaScript で css プロパティを使用して HTML 要素の背景色を設定する方法
-
[解決済み] JavaScriptのArray.sort()メソッドでシャッフルするのは正しいのか?