user2024080
user2024080

Reputation: 5101

How does variable declaration differ between the `class` and `constructor`?

I have seen an example, and I am trying to reproduce it. The name and age are declared inside the class and services ( Injectable ) added in the constructor.

I'd like to know the difference between declaring variable with class and constructor here. Any one help me to know the differences.

As well instead of declaring the name and age can't I declare inside of the constructor itself?

here is my code :

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

    }

Upvotes: 18

Views: 42980

Answers (3)

Konstantin Dinev
Konstantin Dinev

Reputation: 34915

As the variables are defined, they are members of the Component1 class and any instance of the Component1 class has a name and an age public members of respectively string and number types.

After the TypeScript is transpiled, there is no difference whether you declare them in the constructor, or as members. Before it's transpiled however, you have access to these members from instances of this class. This allows you to see errors while you're developing, like for example trying to set the age of a Component1 to something different from a number.

var x = new Component1(a, b);
x.age = "a"; // IDE/editor shows you have a problem here.

The difference comes when you define a class member to be private. Then there is difference after the transpilation.

Here's some docs on TS classes.

Upvotes: 2

Angel Angel
Angel Angel

Reputation: 21756

in this case

export class Component1 {

      constructor ( 
        private _commonService : CommonService, 
        private _commonServiceIndipendent:commonServiceIndipendent) {


       }

is similar to this

export class Component1 {

      private _commonService : CommonService;
      private _commonServiceIndipendent:commonServiceIndipendent;

      constructor ( 
        _commonService : CommonService, 
        _commonServiceIndipendent:commonServiceIndipendent) {

        this._commonService = _commonService; 
        this._commonServiceIndipendent = _commonServiceIndipendent;

       }

if you do not use in the constructor protected, private, or public, for example, DI, the range of the variable _commonService is the scope of the constructor { } you could not use from another function.

for example:

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'.  

       }

If you not assign it to another variable that has the scope of the class,so you no could refer to this variable, with this keyword.


export class Component1 {

  name:string; //why here?
  age:number; //why here?

//can't i add to constructor? if so how?

in typescript without Angular2, you can do this with nothing more:

constructor (name:string, age:number) {}

but in typescript with Angular2, Angular2 is responsible, most of the time, to make use of DI for exaple here:

constructor (private _commonServiceIndipendent:commonServiceIndipendent){}

you use for that providers:[commonServiceIndipendent].


Angular2: Inject a non @Injectable class

How to use Dependency Injection (DI) correctly in Angular2?

Upvotes: 11

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658263

If you delcare a field outside of the constructor it's available for tools that do static analysis, like a linter or autocompletion.

If you add fields in the constructor, such tools would need to analyze the code flow (there could be if, for, ...) in the constructor and it could depend on constructor parameters if fields are actually created or not. This makes it quite difficult and is usually not supported.

Declaring the fields outside the constructor is for a more static approach like in compiled languages. Creating them in the constructor is a dynamic approach usually not available in compiled languages.

If it's only for initializing the fields with literal values it's also more concise. You often might not even need a constructor at all.

class MyClass {
   startValue:number = 1;
}

There is also another way using a constructor

class MyClass {
  constructor(private someField:string) {}
}

which also creates a private field (could also be public). This way also makes the field known for static analysis, because the field is created unconditionally (not dependent on values only known at runtime)

Upvotes: 4

Related Questions