3

読みやすさはさておき...効率や機能の観点から、宣言をループの外側(私の練習)に配置するか、ループの内側(他のSOの投稿に見られる)に配置するかの違いがわかりません。または、そのことについては、なぜコード宣言がまったくないのですか?ここにいくつかの退化した例があります...以下にもっとコメントがあります。

A1:

var x;
for (i=0; i<10; i++){
    x = i;
 }

A2:

for (i=0; i<10; i++){
    var x = i;
 }

B1:

var i;
for (i=0; i<10; i++){
 }

B2:

for (var i=0; i<10; i++){
 }

C1:

var x;
var y;

C2:

var x, y;

読みやすさはさておき...B1とB2、C1とC2の間に違いはないと思いますが、A1とA2の効率や機能の違いには不安があります。また、同じ名前のグローバル変数との競合の可能性を排除するために関数で宣言を使用することを除いて、宣言にどのような利点があるのか​​わかりません。

編集:いくつかのセミコロンを追加しました

編集:最初の文の明快さ、機能を機能に変更

編集:私が作成した以下のコメントを支援するために、以下にいくつかのコードを追加します編集:コメント

<!doctype html>
<html>
<head>
<script type='text/javascript'>
var w = (function(){  // wrapper
    alert('init');
    function p(){ // private
        alert('p');
        w.b(); //needs prefix
    }
    return{
        a: function(){ // public
            alert('a'); 
            p();
            w.b(); // needs prefix 
        },
        b: function(){ // public
            alert('b'); 
        }
    };
})(); // execute immediately
</script>
<script type="text/javascript">window.onload=w.a;</script>
</head>
<body>
sequence of alerts will be 'init' 'a' 'p' 'b'
</body>
</html>
4

4 に答える 4

3

変数宣言は、関数の先頭まで引き上げられます。もちろん、新しい関数スコープで変数を宣言することについて話しているのでない限り、違いはありません。


編集:最初は気づかなかった、あなたの最初の例はで宣言iしなかったvar。それは良い習慣ではありません。


編集:

一般に、グローバルを設定している可能性のある他のスクリプトとの競合を避けるために、グローバル変数の作成を避けることをお勧めします。

で宣言せずに変数を使用すると、変数varはグローバルになります。

JavaScriptで新しい変数スコープを作成する唯一の方法は、関数の本体にあります。関数は相互にネストして、最も内側の関数で始まり、グローバルスコープで終わるスコープチェーンを作成できます。

このため、すぐに呼び出される関数にすべてのコードを配置するのが一般的です。そうすれば、作成する変数がvarグローバルになることはありません。

(function() {   // <-- create a function

    // place your code in here

      // use "var" when declaring variables so they don't become global
    var name = "patrick dw";

    alert( name );

})(); // <-- invoke the function immediately so your code runs

前の例では、name変数はすぐに呼び出される関数に対してローカルであり、グローバルスコープを汚染しません。

変数スコープをトラバースするにはいくつかのリソースが必要なため、のようにいくつかの引数が渡された状態でその関数を呼び出すのが一般的ですwindow

(function( window, undefined ) {

      // now the window object is referenced locally. Better for performance.

    var name = "patrick dw";

    alert( name );

})( window ); // <-- invoke the function passing in the global "window" object

これで、windowオブジェクトは関数内でローカルに参照されるため、のプロパティにアクセスする場合、window関数の外部でスコープチェーンをたどる必要はありません。

また、関数に追加のundefinedパラメーターを含めましたが、引数を渡しませんでした。これは、いくつかの悪いコーディング慣行によって引き起こされる奇妙な問題を回避するのに役立ちます。しかし、それは別の問題です。

var同じ関数を使用して、変数の宣言に使用しなかった場合、name変数は自動的にグローバルになります。例を更新し、説明のために別の関数スコープを追加します。

(function( window, undefined ) {

          // create a function 
    function some_func() {

        name = "patrick dw";  // didn't use "var" when declaring!!
        alert( name );
    }

    some_func();  // call our function

    alert( window.name ); // but "name" is also accessible from the global window

})( window );

alert( name ); // outside those functions, we're global, and again we can see that
               //   the "name" variable is accessible

ご覧のとおり、宣言したことはないvar nameため、2つの関数の深さでネストされていても、自動グローバル変数になりました。

これは多くのエラーの原因であり、の使用には特に注意が必要な理由ですvar


最後に、ECMAScript 5では、でコードを実行するときに、いくつかの悪いコーディング慣行が許可されていないことに注意してください"strict mode";。現在実装しているブラウザは多くありませんstrict modeが、実装しているブラウザでコードを頻繁にテストするのに役立ちます。

ECMAScript5の互換性テーブルは次のとおりです。厳密モードは下部にあります。Firefox4がそれをサポートしていることがわかります。

次に例を示します。

(function( window, undefined ) {

    "strict mode"; // <-- use the strict mode directive

    name = "patrick dw";  // In Firefox 4, you should get a ReferenceError in the console
                          //   because "name" was never declared with "var"
})( window );
于 2011-05-18T20:14:50.650 に答える
1

そのすべての構文の違い。Bでも、両方の宣言は同じスコープにあると思います。

varなしでiを宣言するだけで、グローバルスコープで定義されます。

それは主に、どのオプションが状況に最も適しているかについてですが、それでも可能な限り一貫性を保つ必要があります。

すでにグローバル変数xがある場合、これによって衝突が防止されるとは思いません。

于 2011-05-18T20:23:34.300 に答える
0

を使用する場合、javascript変数のスコープは関数全体で共有されるvarため、A1とA2の両方が関数内にある場合、これらの間に違いはありません。

ただし、letキーワードを使用して、その変数のスコープをブロックに制限することはできます。次に例を示します。

for(let x = 0; x < 10; x++){}

xこれにより、変数がfor{}ブロック内のスコープのみを持つように制限されます。

于 2011-05-18T20:16:08.937 に答える
0

A1とA2の間に機能や効率の違いはありません。これを試して:

var arr=[];
for(var i=0; i<10; ++i) {
  var x=i;
  arr.push( function() {alert(x);} );
}
for(var i=0; i<10; ++i) {
  arr[i]();
}

すべての関数が使用するのと同じxであるため、すべての関数によって示される値が同じであることがわかります。毎回新しい変数が作成されるわけではありません。

于 2011-05-18T20:18:59.843 に答える