ES6中的Proxy有什么用
这篇文章主要介绍了ES6中的Proxy有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
创建一个简单的Proxy
let target = {}
let proxy = new Proxy(target, {})
proxy.name = 'proxy'
console.log(proxy.name) // proxy
console.log(target.name) // proxy
target.name = 'target'
console.log(proxy.name) // target
console.log(target.name) // target
这个实例将"proxy"赋值给proxy.name属性时会在目标上创建name,代理只是简单的将操作转发给目标,他不会储存这个属性。相当于proxy.name和target.name引用的都是target.name的值。
使用set陷阱验证属性
set陷阱接收四个参数:
1.trapTarget:用于接收属性(代理的目标)的对象
2.key:要写入的属性键(字符串或者symbol)
3.value:被写入的属性值
4.receiver:操作发生的对象(通常是代理)
let target = {
name: "target"
}
let proxy = new Proxy(target, {
set(trapTarget, key, value, receiver) {
if (!trapTarget.hasOwnProperty(key)) {
if (isNaN(value)) {
throw new TypeError("属性必须时数字")
}
}
return Reflect.set(trapTarget, key, value, receiver)
}
})
proxy.count = 1
console.log(proxy.count) //1
console.log(target.count) //1
proxy.name = "proxy"
console.log(proxy.name) //proxy
console.log(target.name) //proxy
proxy.other = "other" // 这里会报错因为不数字
这个实例每次在外面改变proxy的值时就会出发set函数。
用get陷阱验证对象结构
get接收3个参数
1.trapTarget:用于接收属性(代理的目标)的对象
2.key:要写入的属性键(字符串或者symbol)
3.receiver:操作发生的对象(通常是代理)
let proxy = new Proxy({}, {
get(trapTarget, key, receiver) {
if (!(key in receiver)) {
throw new TypeError("属性" + key + "不存在")
}
return Reflect.get(trapTarget, key, receiver)
}
})
proxy.name = "proxy"
console.log(proxy.name) //proxy
console.log(proxy.age) // 属性不存在会抛出错误
当我们访问proxy创建的对象属性时就会触发get方法
使用has陷阱因此已有属性
has接收2个参数:
1.trapTarget:用于接收属性(代理的目标)的对象
2.key:要写入的属性键(字符串或者symbol)
let target = {
name: "target",
value: 42
}
let proxy = new Proxy(target, {
has(trapTarget, key) {
if (key === 'value') {
return false
} else {
return Reflect.has(trapTarget, key)
}
}
})
console.log("value" in proxy) // false
console.log("name" in proxy) // true
console.log("toString" in proxy) // true
用deleteProperty陷阱防止删除属性
deleteProperty接收2个参数:
1.trapTarget:用于接收属性(代理的目标)的对象
2.key:要写入的属性键(字符串或者symbol)
let target = {
name: "target",
value: 42
}
let proxy = new Proxy(traget, {
deleteProperty(trapTarget, key) {
if (key === "value") {
return false
} else {
return Reflect.deleteProperty(trapTarget, key)
}
}
})
console.log("value" in proxy) // true
let result1 = delete proxy.value
console.log(result1) // false
console.log("value" in proxy) // true
console.log("name" in proxy) // true
let result2 = delete proxy.name
console.log(result2) // true
console.log("name" in proxy) // false
当外部要删除proxy的属性就会触发deleteProperty函数
原型代理陷阱(setProptotypeOf,getPrototypeOf)
setProptotypeOf接收2个参数
1.trapTarget:用于接收属性(代理的目标)的对象
2.proto:作为原型使用的对象
let target = {}
let proxy = new Proxy(target, {
// 访问时调用
getPrototypeOf(trapTarget) {
return null
},
// 改变时调用
setPrototypeOf(trapTarget, proto) {
return false
}
})
let targetProto = Object.getPrototypeOf(target)
let proxyProto = Object.getPrototypeOf(proxy)
console.log(targetProto === Object.prototype) //true
console.log(proxyProto === Object.prototype) // false
console.log(proxyProto) // null
Object.setPrototypeOf(target, {}) // 成功
Object.setPrototypeOf(proxy, {}) // 抛出错误
如果正常实现
let target = {}
let proxy = new Proxy(target, {
// 访问时调用
getPrototypeOf(trapTarget) {
return Reflect.getPrototypeOf(trapTarget)
},
// 改变时调用
setPrototypeOf(trapTarget, proto) {
return Reflect.setPrototypeOf(trapTarget, proto)
}
})
let targetProto = Object.getPrototypeOf(target)
let proxyProto = Object.getPrototypeOf(proxy)
console.log(targetProto === Object.prototype) //true
console.log(proxyProto === Object.prototype) // true
Object.setPrototypeOf(target, {}) // 成功
Object.setPrototypeOf(proxy, {}) // 成功
属性描述符陷阱
defineProperty接收三个参数:
1.trapTarget:用于接收属性(代理的目标)的对象
2.key:要写入的属性键(字符串或者symbol)
3.descriptor:属性的描述对象
let proxy = new Proxy({}, {
defineProperty(trapTarget, key, descriptor) { // descriptor 只能接收enumerable, configurable, value, writeable, get, set
if (typeof key === "symbol") {
return false
}
return Reflect.defineProperty(trapTarget, key, descriptor)
},
getOwnPropertyDescriptor(trapTarget, key) {
return Reflect.getOwnPropertyDescriptor(trapTarget, key)
}
})
Object.defineProperty(proxy, "name", {
value: "proxy"
})
console.log(proxy.name) //proxy
let nameSymbol = Symbol("name")
Object.defineProperty(proxy, nameSymbol, {
value: "proxy"
})
在外部调用defineProperty | getOwnPropertyDescriptor时会触发内部definenProperty | getOwnPropertyDescriptor方法。
ownKeys陷阱
ownKeys陷阱会拦截外部的Object.keys(),Object.getOwnPropertyName(),Object.getOwnPropertySymbols()和Object.assign()四个方法
let proxy = new Proxy({}, {
ownKeys(trapTarget) {
return Reflect.ownKeys(trapTarget).filter(key => {
return typeof key !== "string" || key[0] !== '_'
})
}
})
let nameSymbol = Symbol("name")
proxy.name = "proxy"
proxy._name = "private"
proxy[nameSymbol] = "symbol"
let names = Object.getOwnPropertyNames(proxy),
keys = Object.keys(proxy),
symbols = Object.getOwnPropertySymbols(proxy)
console.log(names.length) // 1
console.log(names) // name
console.log(keys.length) //1
console.log(keys[0]) // name
console.log(symbols.length) //1
console.log(symbols[0]) // symbol(name)
感谢你能够认真阅读完这篇文章,希望小编分享的“ES6中的Proxy有什么用”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341