Neulich bei uns im Slack: Wieso funktioniert das nicht mit dem destructuring?
Siehst Du das Problem? - Wir haben ein bisschen gebraucht, ehrlich gesagt:
class Destructure {
constructor({age, name, nr} = {}) {
var age = age;
var name = name;
var nr = nr;
}
print() {
console.log(this.age + this.name + this.nr);
}
};
let instance = new Destructure(18, 'Ralph', 016255446262);
instance.print();
console.warn('Not working! at ' + new Date(2020, 3, 1, 4, 20).toString());
Alle haben gerufen: Du musst natürlich ein Object im Konstruktor übergeben! Sowas wie:
new Destructure({age: 18, name: 'Ralph', nr: 016255446262});
Aber warum funktioniert das dann immer noch nicht? Oh Mann. Bis mal jemand das var
entdeckt hat.
Es muss natürlich heissen:
constructor({age, name, nr} = {}) {
this.age = age;
this.name = name;
this.nr = nr;
}
var
ist evilNa, was kommt hierbei raus?
var foo = "foo";
function bar() {
console.log(foo);
foo = "bar";
var foo = "baz";
}
console.log(foo);
bar();
console.log(foo);
Auflösung: foo, undefined, foo
Es ist so, dass bei var
das sogenannte Hoisting zum Einsatz kommt. var
-Variablen werden immer innerhalb ihres Scopes zu allererst nur initialisiert, allerdings nicht zugewiesen.
Das var foo="baz"
innerhalb der Funktion sorgt also durch hoising übersetzt dafür:
var foo = "foo";
function bar() {
var foo;
console.log(foo);
foo = "bar";
foo = "baz";
}
console.log(foo);
bar();
console.log(foo);
Bei let wäre es rein technisch sogar das gleiche Spiel, wir haben aber das Glück, dass dank es2015 im Block Scope ein “menschengemachter” Fehler direkt ausgeschlossen wird. Also etwas wie:
var foo = "foo";
function bar() {
console.log(foo);
let foo = "bar"
}
bar();
Führt zu einem Fehler, obwohl man hier keinen erwarten würde.
Es ist also nicht zwingend ein Unterschied zwischen let
und var
(auch wenn es natürlich sehr nah daran ist) sondern ein Unterschied ob Hoisting durch die Umgebung erlaubt ist oder nicht. Bei var
ist es das eben nach wie vor.
Also. Bitte bitte, verwendet niemals var
!
Merkregel: let
deklariert für einen Block (block scoped), also innerhalb von { }
, während var
am Anfang der Funktion deklariert (function scoped). let
funktioniert also wie in jeder anderen Programmiersprache auch, var
ist das wie es PHP macht (bzw. würde, wenn Lerdorf nicht so faul gewesen wäre…).