{}の関数宣言について混乱しています


18

var a;
if (true) {
  a = 5;

  function a() {}
  a = 0;
  console.log(a)
}
console.log(a)

上記のコードを見たところ、関数は{}で宣言されています。0 0と表示されると思いますが、0 5と表示されます。



1
厳密モードでは、ログに記録し0 undefinedます。
特定のパフォーマンス

@certainPerformanceはよく説明できますa = 5が、ブロックが残っていることについては説明できません。だまされたベルギによると、function a巻き上げられます。
Jonas Wilms

2
関数宣言に到達すると、ローカルスコープのブロック変数が外部ブロックにコピーされるように見えます。
Jonas Wilms

回答:


13

次のことが起こります。

(1)2つの変数宣言が存在しますa。1つはブロック内と1つはブロック外です。

(2)関数宣言が巻き上げられ、内部ブロック変数にバインドされます。

(3)a = 5に到達すると、ブロック変数が上書きされます。

(4)関数宣言に到達し、ブロック変数が外部変数にコピーされます。どちらも現在5です。

(5)a = 0に到達すると、ブロック変数が上書きされます。外部変数はこれによる影響を受けません。

 var a¹;
 if (true) {
   function a²() {} // hoisted
   a² = 5;
   a¹ = a²; // at the location of the declaration, the variable leaves the block      
   a² = 0;
  console.log(a²)
}
console.log(a¹);

これは実際には仕様の一部ではなく、Webレガシー互換性セマンティクスの一部であるため、ブロック内で関数を宣言しないください。また、このコードがこのように動作することに依存しないください

これもここで説明されています


しかし、関数宣言に到達すると、ブロック変数が外部変数にコピーされるのはなぜですか?
チョー

@Chorいいえ、仕様にはそう書かれています。なぜか分かりません。
Jonas Wilms
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.