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)

Relaterte artikler