vue3.x用Proxy来代替Object.defineProperty。
Proxy是ES6中提出的一个构造器。通过new Proxy(原对象,{代理列表})
的方式去创建对象,创建的这个对象我们称之为代理对象。
即:
代理对象 = new Proxy(原对象,{代理列表})
之所以要额外产生这么一个代理对象,好处在于可以保持原对象不变,在代理对象中添加新的功能,或者是改造某些功能。
格式
var obj={};
var proxyObj = new Proxy(obj, {
操作1: 函数1,
操作2: 函数2,
...
})
示例
var star = {name: '罗志祥', age: 40,aihao:'运动'}
//Proxy :代理对象
// 通过原对象,产生一个代理对象obj1,代理原对象的 get方法
// 经纪人
var zhaohui = new Proxy(star, {
// 对于obj1,只要执行访问对象的属性,就会执行get函数
// target: 代理原对象,
// prop: 当前要访问的属性名
get:function(target,prop) {
if(prop === 'aihao') {
return '唱歌'
}
else if(prop === 'name') {
return '小猪'
}else {
return target[prop]
}
},
// 给代理对象设置属性时,会执行set
// target: 代理原对象,
// prop: 当前要访问的属性名
// newVal: 要设置的新属性值
set:function(target,prop,newVal) {
console.log(target,prop,newVal)
if(prop === 'age') {
if(newVal > 30) {
console.log('gun......')
}
else {
target[prop] = newVal
}
}
}
})
解释如下:
背景:在我们写js代码的过程中,最容易遇到的是错误是:访问一个对象不存在的属性。而这个时候js代码是不报错的,它只会返回一个undefined.
需求:访问对象的属性时,如果这个属性不存在,则报出一个错误提示。
// 17.proxy应用-访问一个不存在的属性时给提示.html
// 背景:在我们写js代码的过程中,最容易遇到的是错误是:访问一个对象不存在的属性。而这个时候js代码是不报错的,它只会返回一个undefined.
// 需求:访问对象的属性时,如果这个属性不存在,则报出一个错误提示。
var obj = {a:1,b:2}
// console.log(obj.abc123)
var obj1 = new Proxy(obj, {
get:function(target,propName) {
// 如果当前要访问的属性propName在target中:
// - 存在,返回值
// - 不存在,给出提示,再返回undefine
// 格式: 属性名 in 对象
// 功能: 是检查这个属性名在对象中有没有
// 返回值:boolean
if(propName in target) {
return target[propName]
} else {
console.error(propName, '属性不存在')
return undefined
}
}
})
console.log(obj1.a)
console.log(obj1.abc123)
背景:在js中,数组的有效下标是从0开始的。
var arr = [1,2,3];
console.info(arr[0]) // 1
console.info(arr[-1]) // undefined
console.info(arr[100]) // undefined
值得注意的是,下标越界或者是负值的情况下,得到的结果是undefined,而不是报错
。
需求:
如果我们希望数组可以取负值下表,且规则如下:-n表示倒数第n个元素。例如:arr[-1]表示数组arr中的倒数第一个元素。
使用Proxy解决如下:
<script>
// 需求:
// 如果我们希望数组可以取负值下表,且规则如下:-n表示倒数第n个元素。
// 例如:arr[-1]表示数组arr中的倒数第一个元素。
var arr = [1,2,3,4]
// arr[3] = 4;
// 目标:
// arr[-1] = arr[3] = 4
// arr[-2] = arr[2] = 3
// .....
// arr[-n] = arr[arr.length - n]
var arr1 = new Proxy(arr,{
get: function(target,prop) {
console.log(target,prop)
// 判断是数字
if(false === isNaN(prop)) {
var idx = Number(prop)
// 是不是负数
if(idx < 0) {
idx = target.length + idx
}
return target[idx]
} else {
return target[prop]
}
}
})
console.log(arr1[-1])
</script>
在new Proxy的第二个参数中,可以设置的代理属性如下:
var proxyObj = new Proxy(obj, {
get: function(tagert,key,receiver){},
set: function(tagert,key,value){},
has: function(tagert,key){},
deleteProperty: function(tagert,key){},
ownKeys: function(tagert){},
getOwnPropertyDescriptor: function(tagert,key){},
defineProperty: function(tagert,key,desc){},
preventExtensions: function(tagert){},
getPrototypeOf: function(tagert){},
isExtensible: function(tagert){},
setPrototypeof: function(tagert,proto){},
apply: function(tagert,obj,args){},
construct: function(tagert,args){},
})