typescript - Hvordan skiller variabeldeklarasjon seg mellom `class` og `constructor`?
Jeg har sett et eksempel, og jeg prøver å gjenskape det. name og age er deklarert inne i class og services (Injectable) lagt til i constructor.
Jeg vil gjerne vite forskjellen mellom å erklære en variabel med class og constructor her. Kan noen hjelpe meg med å forstå forskjellene.
I stedet for å erklære name og age, kan jeg ikke erklære dem inne i selve constructor?
her er koden min :
import {Component} from 'angular2/core';
import {CommonService} from './commonService';
import {commonServiceIndipendent} from './commonSerivceIndipendent';
@Component({
selector : 'component1',
template : `
<h1>Component 1</h1>
<input type="text" #message />
<button (click)="onLog(message.value)" >Component1 - Message </button>
`,
providers:[commonServiceIndipendent]
})
export class Component1 {
name:string; //why here?
age:number; //why here?
//can't i add to constructor? if so how?
constructor (
private _commonService : CommonService,
private _commonServiceIndipendent:commonServiceIndipendent) {}
//sending to same service. it has other instance in history
onLog(message:string) {
this._commonService.log( message );
this.name = "Arif",
this.age = 20;
this.onData();
}
onData() {
this._commonServiceIndipendent.myData(this.name,this.age);
}
}
Svar #1
i dette tilfellet
export class Component1 {
constructor (
private _commonService : CommonService,
private _commonServiceIndipendent:commonServiceIndipendent) {
}
er lik dette
export class Component1 {
private _commonService : CommonService;
private _commonServiceIndipendent:commonServiceIndipendent;
constructor (
_commonService : CommonService,
_commonServiceIndipendent:commonServiceIndipendent) {
this._commonService = _commonService;
this._commonServiceIndipendent = _commonServiceIndipendent;
}
hvis du ikke bruker i konstruktøren protected, private eller public, for eksempel DI, er omfanget av variabelen _commonService begrenset til konstruktørens { } omfang, og du kunne ikke bruke den fra en annen funksjon.
for eksempel:
export class Component1 {
constructor (
_commonService : CommonService,
_commonServiceIndipendent:commonServiceIndipendent) {
_commonService .... Work
}
foo(){
_commonService ..... Cannot find name '_commonService'.
this._commonService ..... Property '_commonService' does not exist on type 'yourClass'.
}
Hvis du ikke tilordner det til en annen variabel som har klasseomfang, kan du ikke referere til denne variabelen med this-nøkkelordet.
export class Component1 {
name:string; //why here?
age:number; //why here?
//can't i add to constructor? if so how?
i typescript uten Angular2, kan du gjøre dette med ingenting mer:
constructor (name:string, age:number) {}
men i TypeScript med Angular2, er Angular2 ansvarlig, mesteparten av tiden, for å bruke DI for eksempel her:
constructor (private _commonServiceIndipendent:commonServiceIndipendent){}
du bruker for det providers:[commonServiceIndipendent].
Angular2: Injiser en ikke-@Injectable-klasse
Hvordan bruke Dependency Injection (DI) riktig i Angular2?
Svar #2
Hvis du erklærer et felt utenfor konstruktøren, er det tilgjengelig for verktøy som utfører statisk analyse, som en linter eller autokomplettering.
Hvis du legger til felter i konstruktøren, ville slike verktøy måtte analysere kodeflyten (det kan være if, for, ...) i konstruktøren, og det kan avhenge av konstruktørparametere om feltene faktisk blir opprettet eller ikke. Dette gjør det ganske vanskelig og støttes vanligvis ikke.
Å erklære feltene utenfor konstruktøren er for en mer statisk tilnærming som i kompilert språk. Å opprette dem i konstruktøren er en dynamisk tilnærming som vanligvis ikke er tilgjengelig i kompilert språk.
Hvis det bare er for å initialisere feltene med bokstavelige verdier, er det også mer konsist. Du trenger ofte kanskje ikke engang en konstruktør i det hele tatt.
class MyClass {
startValue:number = 1;
}
Det finnes også en annen måte ved å bruke en konstruktør
class MyClass {
constructor(private someField:string) {}
}
som også oppretter et private-felt (kan også være public). Denne måten gjør også feltet kjent for statisk analyse, fordi feltet opprettes ubetinget (ikke avhengig av verdier som bare er kjent ved kjøretid)
