【问题标题】:How does variable declaration differ between the `class` and `constructor`?`class` 和 `constructor` 之间的变量声明有何不同?
【发布时间】:2016-03-22 06:52:48
【问题描述】:

我看到了一个例子,我正在尝试重现它。 nameageclassservices ( Injectable ) 中声明,在 constructor 中添加。

我想知道在这里用classconstructor 声明变量之间的区别。任何人都可以帮助我了解差异。

除了声明 nameage 之外,我不能在 constructor 本身内部声明吗?

这是我的代码:

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

    }

【问题讨论】:

    标签: typescript angular


    【解决方案1】:

    定义变量时,它们是Component1 类的成员,Component1 类的任何实例都有一个name 和一个age 分别属于stringnumber 类型的公共成员。

    TypeScript 转译后,在constructor 中声明它们还是作为成员声明它们没有区别。然而,在它被转译之前,您可以从此类的实例中访问这些成员。这允许您在开发过程中看到错误,例如尝试将 Component1age 设置为与 number 不同的值。

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

    当您将类成员定义为私有时,差异就出现了。那么转译后就有区别了。

    Here's 一些关于 TS 类的文档。

    【讨论】:

      【解决方案2】:

      在这种情况下

      export class Component1 {
      
            constructor ( 
              private _commonService : CommonService, 
              private _commonServiceIndipendent:commonServiceIndipendent) {
      
      
             }
      

      类似

      export class Component1 {
      
            private _commonService : CommonService;
            private _commonServiceIndipendent:commonServiceIndipendent;
      
            constructor ( 
              _commonService : CommonService, 
              _commonServiceIndipendent:commonServiceIndipendent) {
      
              this._commonService = _commonService; 
              this._commonServiceIndipendent = _commonServiceIndipendent;
      
             }
      

      如果你没有在构造函数protectedprivatepublic中使用,例如DI,变量_commonService的范围就是你不能使用的构造函数{ }的范围来自另一个函数。

      例如:

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

      如果你没有将它分配给另一个具有类范围的变量,那么你就不能使用this关键字来引用这个变量。


      export class Component1 {
      
        name:string; //why here?
        age:number; //why here?
      
      //can't i add to constructor? if so how?
      

      在没有 Angular2 的 typescript 中,你可以做到这一点:

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

      但是在带有 Angular2 的 typescript 中,Angular2 负责,大多数时候,在这里使用 DI 例如:

      constructor (private _commonServiceIndipendent:commonServiceIndipendent){}
      

      你用那个providers:[commonServiceIndipendent]


      Angular2: Inject a non @Injectable class

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

      【讨论】:

      • 感谢您的帖子。我遇到了一个问题。我的类函数无法找到注入构造函数的服务实例。解决方案是我必须在注入构造函数时添加公共/私有或受保护。我正在寻找我需要这样做的原因,在这里我得到了答案。谢谢@Angel
      • 在您的示例_commonService .....找不到名称'_commonService'。只需在构造函数()中添加私有或公共即可解决错误。还是不?
      【解决方案3】:

      如果您在构造函数之外删除字段,则它可用于执行静态分析的工具,例如 linter 或自动补全。

      如果您在构造函数中添加字段,则此类工具将需要分析构造函数中的代码流(可能有iffor,...),如果字段实际上是,它可能取决于构造函数参数创建与否。这使得它非常困难并且通常不受支持。

      在构造函数之外声明字段是为了一种更静态的方法,例如在编译语言中。在构造函数中创建它们是一种动态方法,通常在编译语言中不可用。

      如果它只是用于初始化具有字面值的字段,它也更简洁。您可能甚至根本不需要构造函数。

      class MyClass {
         startValue:number = 1;
      }
      

      还有另一种使用构造函数的方法

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

      这也创建了一个private 字段(也可以是public)。这种方式也使该字段可用于静态分析,因为该字段是无条件创建的(不依赖于仅在运行时才知道的值)

      【讨论】:

        猜你喜欢
        • 2016-11-05
        • 2019-07-25
        • 1970-01-01
        • 2011-09-12
        • 1970-01-01
        • 2019-08-20
        • 1970-01-01
        • 1970-01-01
        • 2012-11-28
        相关资源
        最近更新 更多