對象的屬性是由屬性名name,值key,和其他特性(可讀寫性 writable,可枚舉性enumerable,可配置性configurable)組成的。從ES5開發,提供了getter和setter 可以將屬性值的獲取和設置分別綁定到方法上,稱之為“存取器”。有了getter和setter我們就能夠在屬性值的變更和獲取時實現一些操作。
簡單的getter , setter
直接在對象中創建屬性的getter和setter,並進行測試。
注意語法規則,是通過get和set關鍵字創建的percent屬性的getter和setter函數。get函數是沒有參數的,set函數會將等號右邊的值作為參數。當訪問percent屬性時,會返回_num加%,當設置percent時,會打印日志並將值賦給_num。
使用defineProperty
如何在已有的對象上添加getter和setter呢? Object.defineProperty(obj, prop, descriptor) ,obj為將要操作的對象,prop是將要定義或者修改的屬性名,descriptor是將要被修改或者定義的描述符。看實例
defineProperty()添加或者修改屬性的時候需要注意:
1、數據描述符configurable標志着該屬性能夠被改變,能夠被刪除,默認為false
2、數據描述符enumerable標志着該屬性是否可枚舉,默認為false。只有可枚舉屬性才會在for in中遍歷,Object.keys()中返回。另外,所有的內置方法都是不可枚舉的,eg:toString
3、數據描述符value默認為undefined,writable默認為false。所以defineProperty默認新增的屬性,是不可以被賦值運算符修改的。
4、存取描述符set和get都默認為undefined
5、set/get是不能夠和value或者writable一起用的,因為當是存取器屬性的時候,當設置了set標志着可寫,設置了get就標志着可讀,而value也是通過get函數返回的,所以不能同時使用。
Class中的 getter setter
ES6新增class的概念,改變了構造對象的書寫方式,class中同樣可以設置存取器。
TypeScript中的 getter和setter
Angular項目中使用的是ts,ts的class語法與ES6的稍有不同,通過項目中的一個小栗子記錄下ts中的getter和setter。場景如下,有一個datepicker組件,可以調整時間級別為5分鍾或者天。不同級別時,datepicker組件需要作出不同的調整。
做如下處理: datepicker組件中有@input來接受級別的調整,在set中做一些操作
export class LdatepickerComponent implements OnInit { public _level: Level = 'minite'; @Input() get level (): Level { return this._level; } set level ( value: Level ) { // 修改級別后 重置組件的狀態 doSomething() // 發送新的時間為0 doOther() this._level = value; } }
當選擇不同的級別時,傳入到datepicker組件的level會變化,此時的set會對組件做一些自定義的操作,實現需求。