typescript - 變數宣告在 `class` 和 `constructor` 之間有什麼不同?
我已經看過一個範例,並且正在嘗試重現它。name 和 age 是在 class 內部宣告的,而 services(可注入的)則在 constructor 中新增。
我想知道在這裡使用 class 和 constructor 宣告變數的差別。有人能幫我了解這些差異嗎?
那麼與其宣告 name 和 age,我能不能直接在 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);
}
}
答案#1
在這種情況下
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;
}
如果你在建構函數中沒有使用 protected、private 或 public,例如 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?
在 TypeScript 中,沒有 Angular2,你可以僅用這些來做到這點:
constructor (name:string, age:number) {}
但是在使用 Angular2 的 TypeScript 中,大多數時候,Angular2 負責使用依賴注入,例如在這裡:
constructor (private _commonServiceIndipendent:commonServiceIndipendent){}
你為此使用 providers:[commonServiceIndipendent]。
Angular2:注入非 @Injectable 類別
如何在 Angular2 中正確使用依賴注入 (DI)?
答案#2
如果你在建構子之外聲明一個欄位,它對於進行靜態分析的工具是可用的,例如程式碼檢查工具或自動完成功能。
如果你在建構函數中新增欄位,這些工具將需要分析程式碼流程(建構函數中可能有 if、for 等),而欄位是否實際被建立可能還取決於建構函數參數。這使得情況相當困難,通常是不支援的。
在建構函數之外宣告欄位是一種較靜態的方法,就像在編譯型語言中一樣。在建構函數中建立它們是一種動態的方法,通常在編譯型語言中不可用。
如果只是用文字值來初始化欄位,它也更簡潔。你常常甚至可能根本不需要建構函式。
class MyClass {
startValue:number = 1;
}
還有另一種使用建構函式的方法
class MyClass {
constructor(private someField:string) {}
}
這也會創建一個 private 欄位(也可以是 public)。這種方式也使欄位對靜態分析可見,因為欄位是無條件創建的(不依賴於僅在運行時才能知道的值)
