JavaScript中的對象屬性除了有屬性名和屬性值,還包括其它有意義的特性,好比可寫性、可枚舉性和可配置性,還有setter
和getter
特性,這些特性對開發健壯的庫很是有幫助。
javascript
我在上圖中簡單模擬了一處疑似重污染工廠的用水與排污系統模型,經過類比可視化幫助我理解JavaScript對象屬性的4個特性:java
回到JavaScript中,假設有對象factories
,表示所有重污染工廠的集合:算法
var factories = {}
複製代碼
一家名爲sb-1
的污染工廠進入相關部門監控範圍,因而在factories
中加入新屬性:bash
Object.defineProperty(factories, 'sb-1', {
writable: true,
enumerable: true,
configurable: true
})
複製代碼
writable:true
在JavaScript中表示可寫性,圖中表示sb-1
工廠的排污開關是打開狀態;enumerable:true
在JavaScript中表示可枚舉性,圖中表示sb-1
工廠的水錶正常運行中,等着相關部門來查水錶;configurable:true
在JavaScript中表示可配置性,圖中表示sb-1
工廠的總控臺是通電運行狀態。除了上面做爲例子的1號污染工廠sb-1
,還有2號、3號、4號等等都在相關部門監管範圍內。相關部門開始查水錶,只需遍歷factories
,若是檢測到屬性值爲"污水"
觸發警報:網絡
for(let factory in factories){
console.log(`即將查工廠「${factory}`」的水錶) // 即將查工廠「sb-1」的水錶
check(factories[factory]) // 嘟嘟嘟!污水!限期整改!
}
複製代碼
查水錶的前提條件是:工廠的水錶必須是正在運行中。函數
sb-1
工廠向環境中排放未過濾污水,爲了繞過審查,將工廠水錶關掉了:ui
Object.defineProperty(factories, 'sb-1', {
value: "污水"
enumerable: false,
})
複製代碼
這樣一來,相關部門再次遍歷factories
中的全部工廠,不在審查工廠sb-1
,廠長得意地笑了,小聰明也。spa
相關部門也不是吃素的,當即採起措施,審查組到污染工廠將排污閥門關閉,整改1個月:設計
Object.defineProperty(factories, 'sb-1', {
writable: false
})
複製代碼
這下,sb-1
工廠一個月不能再寫髒了,廠長有小聰明吖,偷偷把排污閥門又打開了:code
Object.defineProperty(factories, 'sb-1', {
writable: true
})
複製代碼
這一次相關部門被惹怒,沒手軟,果斷出手整治,污染工廠直接歇菜:
Object.defineProperty(factories, 'sb-1', {
enumerable: false,
writable: false,
configurable: false
})
複製代碼
水錶關閉;排污閥門關閉。總控臺一旦被斷電,重污染工廠關門大吉。
相關部門要批量關閉多個污染工廠,會這樣作:
Object.defineProperties(factories, {
'sb-1':{configurable: false},
'sb-2':{configurable: false},
'sb-3':{configurable: false}
})複製代碼
另外,getter
和setter
也屬於屬性特性,它們是函數:
Object.defineProperty(factories, 'sb-1', {
get: function(){
return '污水'
},
set: function(){},
writable: false,
configurable: false
})
複製代碼
若是工廠將getter
函數的算法設計爲:
當水源被檢測時返回(排出)"淨水"
,當未被檢測時返回(排出)"污水"
,emmmm???
檢測對象屬性特性可使用Object.getOwnPropertyDescriptor()
,第一個參數傳入對象,第二個參數傳入要查詢的屬性名:
Object.getOwnPropertyDescriptor(factories, "sb-1")
複製代碼
現實世界裏,工廠正將污水肆無忌憚地排入河裏;
虛擬世界裏,噴子和鍵盤俠們正在網絡裏捍衛「正義」。
原創做者:帥華君