javascript - Hvorfor har TypeScript brug for præfikset "this." for "interne" moduler?
Der er to måder at definere moduler i TypeScript på:
"Enlig" livsstil:
import app = require("durandal/app");
import ko = require("knockout");
export var name = ko.observable();
export function sayHello() {
app.showMessage('Hello ' + name() + '! Nice to meet you.', 'Greetings');
}
"Forbigående" livsstil:
import app = require("durandal/app");
import ko = require("knockout");
class AnythingYouLike {
name = ko.observable();
sayHello() {
app.showMessage('Hello ' + this.name() + '! Nice to meet you.', 'Greetings');
}
}
export = AnythingYouLike;
Jeg bruger citationstegn omkring mine navne for disse forskellige måder at definere et modul på, da jeg ikke kan finde ud af, hvad de "officielle" navne længere er.
Brugen af "transient"-stilen, især når man bruger et framework som Durandal, giver god mening, da man får bedre kontrol over livsstilen for viewmodel-modulerne og undgår akavede fejl. En ulempe er, at man skal bruge "this" overalt, hvilket har to problemer:
- At ændre en modul fra den ene stil til den anden er kedeligt.
- At have
this.spredt overalt er støjende.
Hvorfor er det egentlig nødvendigt at bruge this. overhovedet, og hvorfor er det ikke nødvendigt i begge stilarter?
Svar #1
Dette handler ikke så meget om moduler, som det handler om det faktum, at i den anden "stil" er name et medlem på AnythingYouLike klasse, mens du i den første "stil" erklærer det som en uafhængig variabel i det globale rum.
this giver mening i det første tilfælde, når man indser, at det bruges af en bestemt instans af den klasse til at henvise til dens egen name - this.name, læs: "mit navn".
Der er selvfølgelig ingen sådan kontekst i det første eksempel - der opretter du blot name.
@War10ck har ret i at påpege, at dette er en meget grundlæggende OOP-ting.
Som svar på din kommentar:
Men i det andet eksempel er der kontekst (den omgivende klasseerklæring), der burde betyde dette. kan antydes, ikke?
Java fungerer på den måde (det gør andre OOP-sprog også), og semantikken af this er mere eller mindre den samme i TS og Java. Men nej, this kan ikke antydes i TS, det skal være eksplicit.
Bemærk, at dette i høj grad skyldes det faktum, at "singleton-stilen" findes i JS, og dermed indirekte i TS, mens den ikke findes i Java. For at illustrere, overvej hvad der sker, hvis vi kombinerer dine eksempler:
var name = "foo";
class AnythingYouLike {
name = "bar";
sayHello() {
app.showMessage('Hello ' + this.name); // shows: Hello bar
app.showMessage('Hello ' + name); // shows: Hello foo
}
}
name og this.name er begge gyldige referencer her til to forskellige værdier. Der findes ingen tilsvarende konstruktion at forholde sig til i Java.
