AS3では、パフォーマンスを向上させるために、ループ外のすべての変数を初期化する必要があると思います。これはJavaScriptでも同様ですか?どちらが良い/速い/ベストプラクティスですか?
var value = 0;
for (var i = 0; i < 100; i++)
{
value = somearray[i];
}
または
for (var i = 0 ; i < 100; i++)
{
var value = somearray[i];
}
JavaScriptまたはActionScriptには、意味またはパフォーマンスに絶対差なしがあります。
var
はパーサーのディレクティブであり、notは実行時に実行されるコマンドです。関数body(*)のどこかで特定の識別子がvar
で1回以上宣言されている場合、ブロック内のその識別子のすべての使用はローカル変数を参照します。 value
がループ内でvar
として宣言されているか、ループ外で宣言されているか、またはその両方であるかにかかわらず、違いはありません。
そのため、最も読みやすいと思うものを書いてください。関数の最上部にすべての変数を配置することが常に最善であるという点で、Crockfordには同意しません。コードのセクションで変数が一時的に使用される場合は、そのセクションでvar
を宣言する方がよいので、セクションは単独でコピーアンドペーストできます。それ以外の場合、リファクタリング中に、関連するvar
を個別に選択して移動することなく、数行のコードを新しい関数にコピーアンドペーストすると、偶発的なグローバルが発生します。
特に:
for (var i; i<100; i++)
do something;
for (var i; i<100; i++)
do something else;
Crockfordは、2番目のvar
を削除することを推奨します(または、上記のvar
sを削除し、上記のvar i;
を実行します)。ただし、IMOでは、簡単に忘れてしまう余分なコードを関数の上部に置くのではなく、両方のvar
sを保持し、関連するすべてのコードをまとめて保持する方が保守性が高くなります。
個人的には、同じ関数の他の部分で同じ変数名の別の使用があるかどうかに関係なく、コードの独立したセクションで変数の最初の割り当てをvar
として宣言する傾向があります。私にとっては、var
を宣言することは、望ましくないJSいぼです(変数をデフォルトでローカルにした方がよかったでしょう)。 JavaScriptでもANSI Cの[古いリビジョン]の制限を複製することは私の義務ではないと思います。
(*:ネストされた関数本体以外)
言語にはブロックスコープはなく、関数スコープのみがあるため、理論的にはJavaScriptに違いはありません。
パフォーマンスの引数についてはわかりませんが、 Douglas Crockford は、var
ステートメントを関数本体の最初のステートメントにすることを推奨しています。 JavaScriptプログラミング言語のコード規約 :
JavaScriptにはブロックスコープがないため、ブロックで変数を定義すると、他のCファミリ言語の経験があるプログラマを混乱させる可能性があります。関数の上部ですべての変数を定義します。
次の例でわかるように、彼にはポイントがあると思います。関数の先頭で変数を宣言しても、変数i
がfor
ループブロックのスコープ内に保持されていると考えるように読者を混乱させることはありません。
function myFunction() {
var i; // the scope of the variables is very clear
for (i = 0; i < 10; i++) {
// ...
}
}
ECMA-/Javascript
言語hoists
関数の最上部のどこかに宣言されている変数。これは、この言語doesがfunction scope
を持ち、notがblock scope
を持っているため、他の多くのCライクな言語と同様です。
それはlexical scope
とも呼ばれます。
次のように宣言する場合
var foo = function(){
for(var i = 0; i < 10; i++){
}
};
これにより、hoisted
が取得されます。
var foo = function(){
var i;
for(i = 0; i < 10; i++){
}
}
したがって、パフォーマンスに違いはありません(ただし、ここで完全に間違っている場合は修正してください)。
not関数の最上部以外の場所で変数を宣言するためのはるかに優れた引数はreadabilityです。 for-loop
内で変数を宣言すると、この変数はループ本体内でしかアクセスできないという誤った仮定になる可能性があります。これはまったく間違っているです。実際、現在のスコープ内のどこからでもその変数にアクセスできます。
来年、すべてのブラウザにコードをプリコンパイルするJSエンジンが搭載されるため、パフォーマンスの違い(同じコードブロックを何度も解析し、割り当てを実行することによる)は無視できるようになります。
また、必要がない限り、パフォーマンスを最適化しないでください。変数を最初に必要な場所に近づけておくと、コードがきれいになります。マイナス面として、ブロックスコープを持つ言語に慣れている人は混乱するかもしれません。
Chromeで簡単なテストを行いました。ブラウザで fiddle を試して結果を確認します
var count = 100000000;
var a = 0;
console.log(new Date());
for (var i=0; i<count; i++) {
a = a + 1
}
console.log(new Date());
var j;
for (j=0; j<count; j++) {
a = a + 1;
}
console.log(new Date());
var j;
for (j=0; j<count; j++) {
var x;
x = x + 1;
}
console.log(new Date());
結果は、最後のテストに最大8秒かかり、前の2つは最大2秒です。順序に関係なく、非常に繰り返し可能です。
したがって、これは、ループの外側で常に変数を宣言する必要があることを証明しています。好奇心が強いのは、for()ステートメントでi
を宣言する最初のケースです。これは、インデックスを事前に宣言する2番目のテストと同じくらい速いようです。
もう1つの考慮事項は、ES2015でlet
とconst
が用意されたため、変数をループブロック専用にスコープできることです。したがって、ループの外側で同じ変数が必要でない限り(または、各反復が前の反復でその変数に対して行われた操作に依存する場合)、おそらくこれを行うのが望ましいでしょう:
for (let i = 0; i < 100; i++) {
let value = somearray[i];
//do something with `value`
}
JavaScriptはCまたはC++によって下部に記述された言語であり、どちらの言語かはよくわかりません。また、その目的の1つは、内部メモリを処理する方法を節約することです。 CまたはC++でも、変数がループ内で宣言されたときに大量のリソースを消費するかどうかを心配する必要はありません。 JavaScriptでそれを心配する必要があるのはなぜですか?
まあ、それはあなたが達成しようとしているものに依存します... value
がループブロック内の一時変数のみであると仮定した場合、2番目の形式を使用する方がはるかに明確です。また、より論理的で冗長です。
Forループの内側または外側で変数を宣言しても違いはありません。以下はテストするサンプルコードです。
function a() {
console.log('Function a() starts');
console.log(new Date());
var j;
for (j=0; j<100000000; j++) {
var x;
x = x + 1;
}
console.log(new Date());
console.log('Function a() Ends');
}
a()
function b() {
console.log('Function B() starts');
console.log(new Date());
var a;
var j;
for (j=0; j<100000000; j++) {
a = a + 1;
}
console.log(new Date());
console.log('Function B() Ends');
}
b()
結果は私の場合に示した
Function a() starts
VM121:3 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:9 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:10 Function a() Ends
VM121:14 Function B() starts
VM121:15 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:21 Thu Apr 12 2018 15:20:26 GMT+0530 (India Standard Time)
VM121:22 Function B() Ends
ありがとう-MyFavs.in