的確寫Proxy文章不少,那麼今天我也不湊字數了,炒兩個栗子吧。數組
const person = {
name: 'xiaoyun',
province: '江蘇省',
city: '南京市'
}
複製代碼
對於上述對象,咱們可能須要地址信息(由省市拼接而成),在此以前咱們可能會採起下列方式:ui
第一個方法的主要弊端是污染了原有的對象,而第二種方法就很不靈活。如今咱們能夠經過Proxy實現比較好的效果:this
const enhancePerson = new Proxy(person, {
get (target, name) {
switch (name) {
case 'address':
return `${target['province']}-${target['city']}`
default:
return target[name]
}
}
})
enhancePerson.address // 江蘇省-南京市
複製代碼
經過這種方式咱們就能夠實現虛擬屬性了,由於它不會被遍歷出來:spa
Object.keys(enhancePerson) // [ 'name', 'province', 'city' ]
複製代碼
這裏還有一個我以爲比較容易忽略的點:code
person === enhancePerson // false
enhancePerson.city = '蘇州市'
enhancePerson.city === person.city // true
複製代碼
顯然這兩個並非同一個對象,可是我經過改變enhancePerson的city屬性卻影響到了person的city屬性,這就是咱們一般會忽略掉的,若是你不設置Proxy的set方法,它會保持默認行爲:cdn
set (target, propKey, value) {
target[propKey] = value
}
複製代碼
可能有些同窗會想不就是不讓它遍歷出來嗎?看這招:對象
const person = {
name: 'xiaoyun',
province: '江蘇省',
city: '南京市',
get address () {
return `${this.province}-${this.city}`
}
}
const enhancePerson = new Proxy(person, {
ownKeys (target) {
return Object.keys(target).filter(item => item !== 'address')
}
})
enhancePerson.address // 江蘇省-南京市
Object.keys(enhancePerson) // [ 'name', 'province', 'city' ]
複製代碼
雖然是實現了上述的功能,可是Proxy中的ownKeys攔截的方法太多,因此咱們攔截ownKeys以後,會致使某些方法沒法使用,而且攔截ownKeys返回的結果也有嚴格的要求:ip
因此在攔截方法注意點不少,否則很容易出現問題。ci
Tip: 未經過defineProperty定義的屬性的描述器屬性默認爲true,不然默認爲false。get
當我第一次接觸Python時,比較有印象的就是它的List的一個語法: arr[1:3],之前只有羨慕的份,如今徹底能夠本身擼一個:
const arr = [1, 2, 3, 4, 5, 6, 7, 8]
const list = new Proxy(arr, {
get (target, name) {
if (name.includes(':')) {
const indexs = name.split(':')
return target.slice(indexs[0], indexs[1])
}
return target[name]
}
})
list['2:6'] // [ 3, 4, 5, 6 ]
複製代碼
是否是😎,對於對象,咱們一樣能夠採用相似的方法:
const obj = {
a: {
b: {
c: 'xiaoyun'
}
}
}
const obj1 = new Proxy(obj, {
get (target, name) {
const keys = name.split('.')
return keys.reduce((pre, next) => {
if (pre !== null && pre !== undefined) {
pre = pre[next]
}
return pre
}, target)
}
})
obj1['a.b.c'] // xiaoyun
複製代碼
喜歡本文的小夥伴們,歡迎關注個人訂閱號超愛敲代碼,查看更多內容.