2016-10-27 8 views
1

さえ巻き上げた後、以下の変更1なぜこのsiteから巻き上げ例を見ると、私は得ることはありません:空の関数宣言はどのようにJavaScriptで巻き上げ作業をしますか?

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

が実際に

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

あるaので、それが10を変化させてはなりませんb関数が返る前にまだ10に割り当てられていますか?なぜ空の関数を呼び出すと、これが起こるのですか?関連するノートでは、なぜ以下の機能は警告を発しませんが、1はまだ変わっていますか? aは、宣言のある関数に再割り当てされませんか?

のは、行ごとにそれを見てみましょう
var a = 1; 
function a() {} 
alert(a); 
+1

'関数A(){}は'だけ 'のようなものですされているだろうですvar a; ' 'b'の' a'は外側の 'a'ではありません。また、 'a'は呼び出されません。 – Xufox

+0

'関数a(){}'は関数のポインタを作成し、 'a = 10'はこのポインタに値を代入/置き換えます。 – Rajesh

+0

の最初のコードスニペットは実際には第2引数として解析されません1。 'a'変数は常に' function a() 'のスコープの外にあります。 – haim770

答えて

4

、ここで

b();あなたは機能bを呼び出します。機能は何ですか?bは体内にありますか?名前がaの新しい関数の宣言。 b内のaにアクセスすると、実際にはグローバル変数aにアクセスしていませんが、今までに宣言した関数です。だから、10はポインタと呼ばれ、aという名前の関数を指すポインタに設定されます。

しかし、最初のコードブロックはなぜ1に警告しますか? aが定義されている

a = 10; 

チェック:JavaScriptエンジンの割り当てを実行するために行くときので、私は

混乱しています。現在のスコープでは、10をaに設定しようとすると、関数宣言があり、その名前はaです。次に上で説明したようになります。しかし、あなたはなぜそう言いますか?関数の宣言は代入の下にあります。これが起こっている理由は、JavaScriptエンジンがまずスクリプト内の宣言を処理し、次にスクリプトの実行に進むという事実です。だから、エンジンがaについて質問すると、aが定義されています。いつものように、現在の範囲を最初に調べます。存在しない場合は、現在のスコープが囲まれているスコープを調べます。あなたの場合、これはグローバルスコープです。私はあなたのコードから推測できます。したがって、あなたがこの関数を定義しなければ、前に言及した第2のステップが完了し、aという変数があるので、その値を変更します。いずれかの変数が存在しない場合、aは、グローバルスコープに定義されているであろう、それは値が10

var a = 1; 
 
function b() { 
 
    a = 10; 
 
    return; 
 
    // I renamed the function from a to c to notice the hoisting 
 
    function c() {} 
 
} 
 
b(); 
 
console.log(a);

+0

しかし、なぜコードの最初のブロックは1を警告しますか?私は混乱しています –

+0

@Reddy _ "[Y] ouは実際にグローバル変数' a' "_にアクセスしません。 – Xufox

+0

@Xufoxでも 'a = 10;'はグローバル定義の 'a'権利にアクセスしますか? –

関連する問題