関数を定義すると
inc = function(x) { return x + 1 }
ネストされた呼び出しを行います
inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(inc(1)))))))))))))))))))))
これにより、値は22
になります。ネストされた式を修正して、代わりにcall
を使用する場合、null
にthis
を渡します。
inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, 1)))))))))))))))))))))
これにより、値22
も生成されます。
しかし、JavaScriptCoreでは、この2番目の形式は[〜#〜] o [〜#〜](2 ^ n)メモリを消費しているように見えます。ここでn =はネストされた呼び出しの数です。 FirefoxまたはChromeでこのJavaScriptを試してみると、これは当てはまらないため、JavaScriptCoreに分離されているようです。
JavaScriptの経験はほとんどありません(ほとんどありません)。さまざまなJavaScript実装がもたらす可能性のあるトレードオフについて、また、サンプルコードが一部の実装(クロージャなどの汎用サポートを提供する)で高価であるのに対し、他の実装では効率的であることが合理的かどうかについてはわかりません。
私の質問は:このコードは本質的に問題がありますか?別の方法で構造化するように書き直す必要がありますか?または、コードは問題ありません。JavaScriptCoreには単にバグがありますか?
一時的なものへの内部呼び出しのいくつかをリファクタリングすると、メモリの倍増動作が「切り捨てられる」という実験を行いました。
var temp1 = inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, 1)))))));
var temp2 = inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, temp1)))))));
inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, inc.call(null, temp2)))))));
この質問へのコメントに基づくと、記述されたコードに根本的な問題はないが、代わりにこれはJavaScriptCoreのバグであるというコンセンサスがあります。
チケット提出 の場合、再現可能であることが確認されており、Appleのレーダーシステムにインポートされています。