verwirrt über Funktionsdeklaration in {}


18

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

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

Ich habe den obigen Code gesehen, eine Funktion ist in {} deklariert. Ich denke, es würde 0 0 drucken, aber es druckt 0 5



1
Im strengen Modus wird protokolliert 0 undefined.
Bestimmte Leistung

@certainPerformance gut, das ist erklärbar, aber ich kann nicht erklären, dass a = 5der Block verlässt. Laut Bergi function awird der Betrogene gehisst.
Jonas Wilms

2
Es scheint, als würde die Blockvariable mit lokalem Gültigkeitsbereich beim Erreichen der Funktionsdeklaration in den äußeren Block kopiert.
Jonas Wilms

Antworten:


13

Folgendes passiert:

(1) Es gibt zwei Variablendeklarationen a, eine innerhalb des Blocks und eine außerhalb des Blocks.

(2) Die Funktionsdeklaration wird angehoben und an die Variable der inneren Blöcke gebunden.

(3) a = 5erreicht ist, wodurch die Blockvariable überschrieben wird.

(4) Die Funktionsdeklaration wird erreicht und die Blockvariable wird in die äußere Variable kopiert. Beide sind jetzt 5.

(5) a = 0erreicht ist, wodurch die Blockvariable überschrieben wird. Die äußere Variable ist davon nicht betroffen.

 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¹);

Dies ist eigentlich nicht wirklich Teil der Spezifikation, sondern Teil der Semantik der Web-Legacy-Kompatibilität. Deklarieren Sie also keine Funktionen innerhalb von Blöcken und verlassen Sie sich nicht auf diesen Code, um sich auf diese Weise zu verhalten .

Dies wird auch hier erklärt


Aber warum wird die Blockvariable nach Erreichen der Funktionsdeklaration in die äußere Variable kopiert?
Chor

@Chor nein, die Spezifikation sagt es. Ich habe keine Idee warum.
Jonas Wilms
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.