TypeScript 1.8
我試圖圍繞如何使用set
訪問器來攔截對象屬性(和子屬性)的編輯操作。它沒有按照我的預期工作,我不知道我的代碼是否有問題。限制ot Typescript設置訪問器或問題與我的代碼?
這裏是我的類的摘錄:
private setAction:number = 0; //track # of edits
private _person:{ //data to be edited
name:string,
data:{
activities:Array<{
activityName:string,
funFactor:number
}>,
country:string
}
};
//public interfaces for set/get operations
public set person(val:any){
//indicate which edit is occuring
console.log('setting _person: setAction='+this.setAction);
if(!this._person) this._person = val;//initial set operation
let p = this._person;
p.name = val.name || p.name;
p.data.activities = val.data.activities || p.data.activities;
p.data.country = val.data.country || p.data.country;
}
public get person(){
return this._person;
}
public addActivity(name:string,value:number){
this.person.data.activities.push(
{activityName:name,funFactor:value});
}
//Edit this.person and test whether Set Accessor is called
onLoad(){
console.log('Incrementing setAction to '+ ++this.setAction);
this.person = {
name:'Mary',
data:{
activities:[],
country:'Argentina'
}
};
console.log('Incrementing setAction to '+ ++this.setAction);
this.person.name = 'Janet';
console.log('Incrementing setAction to '+ ++this.setAction);
this.addActivity('Bowling',7);
console.log('Incrementing setAction to '+ ++this.setAction);
this.person.data.country = 'Mexico';
console.log('Incrementing setAction to '+ ++this.setAction);
this.person.data.activities[0].funFactor = 8;
console.log(this.person);
}
當onLoad
被調用時,下面是輸出到控制檯:
遞增的setAction 1
設置_person:setAction命令= 1
遞增setAction爲2
遞增的setAction至3
遞增的setAction至4
遞增的setAction至5
對象{名: 「珍」,數據:對象}
的data
在最終Object
更新爲country="Mexico"
和Bowling funFactor=8
。所以所有編輯都成功完成,但Set
訪問器只被調用一次。爲什麼是這樣?
看看the docs(向下滾動到訪問器部分)沒有提到這個限制。
其他注意事項: 據我所知,爲了執行person.name='Janet'
,我需要先得到person
,所以我希望get
要對所有這些操作調用。但由於person.name
從'瑪麗'改爲'珍妮特',確實設爲爲一個新值。那麼,爲什麼不是二傳手?我正在努力處理它的邏輯。我期望這個過程是:1)get person
,2)set person.name
。
當屬性從一個值更改爲另一個值時,不應該調用getter和setter嗎?
回答
我一直以爲get
和set
進行時性能讀取或寫入調用。這就是它向我解釋的。 TypeScript文檔說'TypeScript支持getters/setter作爲攔截對象'成員的訪問方式'。 RadimKöhler幫助我理解,當代碼不與對象屬性交互時,而是與對象引用交互時,將調用這些函數。總之,當我執行person.name='Janet'
時,雖然屬性值發生變化,但person
仍然是指內存中的同一個對象,所以沒有set
操作。
我明白,爲了執行'person.name ='Janet'',我需要先得到'person',所以我希望'GET'是正如你所提到的那樣呼籲所有這些行動。然而,由於'person.name'從'Mary'變成了'Janet',它確實**將**設置爲一個新值。那麼,爲什麼不是二傳手?我正在努力處理它的邏輯。我期望的過程是:1)'get person',2)'set person.name' – BeetleJuice
那麼1)得到人..意味着給我參考人。因此,當我們改變名稱時,我們在內存中有一個地址(這是參考),其中人員實例是2)。我們不會改變對人的引用。它仍然是同一個對象..只是某處(在堆上)改變了它的設置名稱。因此,這個人的二傳手是真實的,以引用這個人。不涉及與該實例相關的屬性。也許試着準備一些關於引用和值類型的東西。 http://www.zsoltnagy.eu/understand-value-and-reference-types-in-javascript/ –
我對引用類型和值類型之間的區別有所瞭解(感謝您的鏈接;我會看一看) 。我不知道「* setter是真的引用,而不是屬性*」這是有道理的,但我鏈接到的Typescript文檔沒有提及它。你有沒有參考這個,你可以添加到你的答案? – BeetleJuice