[解決済み] Javascriptのarguments.calleeは何のためにあるのでしょうか?
質問内容
この変数に関するクロスブラウザの完全なドキュメントを見つけられませんでした。
とは何ですか?
arguments.callee
どのように機能するのですか?
どのような引数があるのですか?
どのように解決するのですか?
arguments.callee
は、現在呼び出されている関数への参照です。まず最初に、これを使わないでください。厳格なコンテキストであれば、エラーを吐き出すだけでしょう。
ただし、個人的には -and これは私一人ではありません - このプロパティがないと寂しいですね。その理由を説明する前に、このプロパティを使う場合の擬似的な例を挙げておきます。
var looper = (function(someClosureVar)
{
setTimeout((function(resetTimeout)
{
return function()
{
//do stuff, stop OR:
resetTimeout();
};
}(arguments.callee)),1000);
}(document.getElementById('foobar')));
クロージャが好きならいいんですが、私は好きなので、そこで
arguments.callee
が発生する可能性が非常に高いです。最後から2番目の行は、お金があるところです。
(arguments.callee)
クロージャスコープ(この場合、1つのDOM要素にアクセスできる)内の、最初のタイムアウトを設定する匿名関数への参照です。匿名関数は返した後にGCされますが、今回はタイムアウトコールバックのスコープに追加しているので(実際のコールバックを返す別の匿名関数に引数として渡しています)、まだどこかで参照されている状態です。
さて、もしあなたがストリクトモードなら、このようなコードになるので心配する必要はないでしょう。
var looper = (function tempName(someClosureVar)
{
setTimeout((function(resetTimeout)
{
return function()
{
//do stuff, stop OR:
resetTimeout();
};
}(tempName)),1000);
}(document.getElementById('foobar')));
関数に名前をつけて、それでおしまい。なぜ嫌なんだろう?
arguments.callee
は、匿名関数と同じように、クロージャーのトリックが行われていることを示すフラグです。これは単なる習慣なのでしょうが、自分のコードをより簡単に構成し、デバッグするのに役立っていると思います。
さらに、クライアントサイドスクリプティングをする人なら当然知っているIEへの病的な憎しみがあります。ストリクトモードをサポートしないIEのバージョンは、以下のような傾向があります。
リーク
そのため、関数(と作成したクロージャ)に関連するメモリがGCされることは決してありません。そのため、関数(と作成したクロージャ)に関連するメモリがGCされることはありません。これは、循環参照や、さらに悪いことに、循環DOM参照につながり、メモリリークにつながる可能性があります。
実は
もうひとつ、実際の例を挙げましょう。
どこの
arguments.callee
は、イベントの委譲とイベントリスナーのデタッチに使用されます。
詳しくはこちら
を使用したJSストリクトモードと再帰について説明します。
arguments.callee
.
最後の質問は、IMOの最も明確な例です。
arguments.callee
は、再帰的な置換関数が便利です。
function someF(foo)
{
//'use strict'; <-- would throw errors here
foo = foo.replace(/(a|b)+/gi, function (p1,p2)
{
if (p1.match(/(a|b){2,}/i))
{
return p1.replace(/(a|b)/gi,arguments.callee);//recursive
}
return (p2.match(/a/i) ? 'X':'Y');
});
}
ご要望にお応えして
引数.callee
MDN では、ストリクトモードでの使用について警告しています (ECMA 5、DC が arguments.callee を非推奨としている理由がわかります)。
そして
ストリクトの詳細
関連
-
[解決済み] jQueryで、ユーザーがそのフィールドを編集している間、テキストフィールドの最初の文字を大文字にするにはどうすればよいですか?
-
[解決済み】TypeError: res.status は関数ではありません。
-
[解決済み】ES6マップオブジェクトをソートすることは可能ですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
-
[解決済み】JavaScriptの関数にデフォルトのパラメータ値を設定する
-
[解決済み】オブジェクトからプロパティを削除する(JavaScript)
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】TypeError: $(...).DataTable は関数ではありません。
-
[解決済み】node.js TypeError: path must be absolute or specify root to res.sendFile [JSONのパースに失敗しました]。
-
[解決済み】XMLHttpRequestモジュールが定義されていない/見つからない
-
[解決済み】エラー:リスン EACCES 0.0.0.0:80 OSx Node.js
-
[解決済み】FirefoxでGoogle Maps V3をリモートで使用すると「googleが定義されていません」と表示される。
-
[解決済み】Kendo Observable Bindingと併用する場合、Kendo Switch Labelsを変更することは可能ですか?[Kendo-UI]です。
-
[解決済み】Jestが予期しないトークンに遭遇した
-
[解決済み】ES6マップオブジェクトをソートすることは可能ですか?
-
[解決済み】Uncaught ReferenceError。Firebase は定義されていません。
-
[解決済み】Babel NodeJS ES6: SyntaxError: 予期しないトークンのエクスポート