web-dev-qa-db-ja.com

JavaScript「ホイスト」

JavaScriptの「巻き上げ」に遭遇しましたが、このコードスニペットが実際にどのように機能するかわかりませんでした。

_var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}

b();
alert(a);
_

function a() {})のような関数宣言は、関数bスコープの最上部に引き上げられますが、aの値をオーバーライドしないでください(関数のため)宣言は変数の宣言をオーバーライドしますが、変数の初期化はオーバーライドしません)。したがって、アラートの値は1ではなく10になると予想しました!!

83
morfioce
  1. グローバルaは_1_に設定されます
  2. b()が呼び出されます
  3. function a() {}はホイストされ、グローバルaをマスクするlocal変数aを作成します
  4. ローカルaは_10_に設定されます(関数aを上書きします)
  5. グローバルa(まだ_1_)がアラートされます
111
Quentin

これは、この例のコンパイル/解釈の順序がやや誤解を招くためです。 function a () {}行は、関数の残りのいずれかが実行される前に解釈されるため、関数の最初の部分では、aの値はfunction a () {}になります。それを_10_に再割り当てすると、関数b()のローカルスコープでaの値を再割り当てします。グローバルスコープの_a = 1_。

これを確認するには、alert() sなどを適切な場所に配置して、さまざまなポイントでaの値を確認します。

6
fraveydank

(1)JavaScriptにはブロックステートメントスコープがありません。むしろ、ブロックが存在するコードに対してローカルになります。

(2)Javascriptの関数スコープ内の変数の宣言。つまり、関数で宣言された変数は、値が割り当てられる前であっても、その関数内のどこでも使用可能

(3)関数の本体内では、ローカル変数は同じ名前のグローバル変数よりも優先されます。 グローバル変数と同じ名前のローカル変数または関数パラメーターを宣言する場合、実質的にグローバル変数を非表示にする

コードは次と同じです:(read comment

<script>
var a = 1;          //global a = 1
function b() {
    a = 10;         
    var a = 20;     //local a = 20
}
b();
alert(a);           //global a  = 1
</script>

参照:
(1) JavaScript変数スコープ:
(2) Javascriptの巻き上げの危険な例
(3) 変数スコープ

あなたのコードで:

var a = 1;          //global a = 1  
function b() {
    a = 10;         
    return;
    function a() {} //local 
}
b();
alert(a);           //global a = 1  
5
Grijesh Chauhan
  1. 関数宣言function a(){}が最初に巻き上げられるため、ローカルスコープにaが作成されます。
  2. 同じ名前の2つの変数(1つはグローバル、もう1つはローカル)がある場合、ローカル変数は常にグローバル変数よりも優先されます。
  3. a=10を設定すると、グローバル変数ではなくローカル変数aが設定されます。

したがって、グローバル変数の値は同じままで、警告が表示されます1

2
KhanSharp

JavaScript Scoping and Hoisting と同じ記事を読んだとき、著者は2つの冒頭のサンプルコードがコンパイラーで解釈されるものを見せたことがないので、私も混乱しました。

ここにあなたが提供した例と、ページの2番目があります:

var a = 1;
function b() {
    function a() {} // declares 'a' as a function, which is always local
    a = 10;
    return;
}
b();
alert(a);

ページの最初の例は次のとおりです。

var foo = 1;
function bar() {
    var foo; // a new local 'foo' variable
    if (!foo) {
        foo = 10;
    }
    alert(foo);
}
bar();

お役に立てれば

0
Jonathan