3

この記事を読んでいて、いくつか質問があります。

このコードを考慮する:

1:   var a = 1;
2:   function b () {
3:       a = 10;
4:       return;
5:       function a() {}
6:   }
7:   b();
8:   alert(a);

これは1を警告します(私の質問はなぜですか?)

この記事には、名前解決に関連することが記載されています。

名前解決 (記事によると) は、次の順序で決定されています。

1. Internal mechanisms of language: for example, in all scopes are available “this” and “arguments”.
2. Formal parameters: the functions can be named as the formal parameters, which scope is limited to the function body.
3. Function declarations: declared in the form of function foo() {}.
4. Variable declarations: for example, var foo;.

3 行目では、グローバル a の値を変更するとします。しかし、関数 a(){...} は宣言内よりも優先されます (私が正しく理解した場合)、それがアラート 1 の理由です

ps 行番号 5 を削除すると、アラート 10 が表示されます。

一般に、名前が既に定義されている場合、同じ名前を持つ別のエンティティによって再定義されることはありません。つまり、関数宣言は、同じ名前の変数の宣言よりも優先されます。しかし、これは、変数代入の値が関数を置き換えないという意味ではなく、その定義が無視されるだけです。

私はその部分を理解していません:

しかし、これは、変数代入の値が関数を置き換えないという意味ではありません

2つの質問をお願いします:

  • アラート1の理由を正しく理解できましたか?

  • 上記の行はどういう意味ですか? (誤解されている部分)

ありがとう。

4

3 に答える 3

7

警告する理由を正しく理解しましたか1

はい

「しかし、これは変数代入の値が関数を置き換えないという意味ではありません」
上記の行はどういう意味ですか?(誤解された部分)

これは、名前の付いた関数aがすでに定義されていa = 10ても、実行されることを意味します。つまり、その後、その行aは関数を参照せず、を参照し10ます。

前のステートメントを少し緩和して、関数宣言が最初に実行されるため、割り当てがもう行われないと人々が誤って考えるのを避けたいと思ったと思います。


関数と変数の宣言は、スコープの一番上に持ち上げられます。したがって、コードは次のようになります。

1:   var a = 1;
2:   function b () {
3:       function a() {}
4:       a = 10;
5:       return;
6:   }
7:   b();
8:   alert(a);

function a() {...}ローカルスコープにシンボル(変数)を作成し、aその値はまったく同じ関数です。次の行、a = 10;は、そのシンボルに新しい値、つまり数値を割り当てます。

var a = 1;
function b () {
     function a() {} // creates a new local symbol `a`, shadowing the outer `a`
     // until here, `a` refers to the function created 
     // created by the above declaration
     a = 10; // now a new value is assigned to the local symbol/variable `a`
     // from here on, `a` is `10`, not a function
     return;
}
b();
alert(a);
于 2012-09-05T17:53:30.140 に答える
3
var a = 1;
function b () {
    var a = 10;
}
b();
alert(a);

上記の例はあなたにとって意味がありますか?はい?よし、ローカル スコープとグローバル スコープの違いが理解できた...

var a = 1;
function b () {
    a = 10;
    var a;
}
b();
alert(a);

この例はあなたにとって意味がありますか? はい?次に、関数内で変数が宣言されている場所は問題ではないことを理解します。変数は、最初に関数に入るときに常に宣言されます。

var a = 1;
function b () {
    a = 10;
    var a = function() { };
}
b();
alert(a);

さて、この例は理にかなっていますか? はい?次に、動的型付けを理解します。変数には関数を値として割り当てることができ、その後、10 などの整数で上書きできます。

var a = 1;
function b () {
    a = 10;
    return;
    function a() { }
}
b();
alert(a);

宣言する方法を変更しているだけなので、あなたの例は理にかなっていますが、同じことです。

于 2012-09-05T18:06:26.100 に答える
2

巻き上げについての私の理解では、変数宣言と関数宣言の両方が巻き上げられます。そのため、次のことが起こっています。

var a; // a is declared (hoisted)
function b () { // function declaration (hoisted)
    function a () {} // function declaration (hoisted)
    a = 10; // an assignment to the local a that was hoisted, not the outer a
    return;
}
a = 1; // initialization (not hoisted)
b(); // hoist inside b's scope causes an inner a to be modified
alert(a); // alerts 1 since the outer a was never modified
于 2012-09-05T17:57:59.663 に答える