的确写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
复制代码
喜欢本文的小伙伴们,欢迎关注个人订阅号超爱敲代码,查看更多内容.