We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
缺点
defineproperty
proxy
for in
修改原数据
优点
// 拦截器 let obj = {}; let temp = 'Yvette'; Object.defineProperty(obj, 'name', { get() { console.log("读取成功"); return temp }, set(value) { console.log("设置成功"); temp = value; } }); obj.name = 'Chris'; console.log(obj.name);
注意: Object.defineProperty定义出来的属性,默认是不可枚举(enumerable: false),不可更改(writable: false),不可配置(configurable: false)
Object.defineProperty
enumerable: false
writable: false
configurable: false
Proxy 会劫持整个对象,读取对象中的属性或者是修改属性值,那么就会被劫持。但是有点需要注意,复杂数据类型,监控的是引用地址,而不是值,如果引用地址没有改变,那么不会触发set。
let obj = { name: 'Yvette', hobbits: ['travel', 'reading'], info: { age: 20, job: 'engineer' } }; let p = new Proxy(obj, { get(target, key) { //第三个参数是 proxy, 一般不使用 console.log('读取成功'); return Reflect.get(target, key); }, set(target, key, value) { if(key === 'length') return true; //如果是数组长度的变化,返回。 console.log('设置成功'); return Reflect.set(target, key, value); } }); p.name = 20; //设置成功 p.age = 20; //设置成功; 不需要事先定义此属性 p.hobbits.push('photography'); //读取成功;注意不会触发设置成功 p.info.age = 18; //读取成功;不会触发设置成功
最后,我们再看下对于数组的劫持,Object.definedProperty 和 Proxy 的差别
Object.definedProperty 可以将数组的索引作为属性进行劫持,但是仅支持直接对 arry[i] 进行操作,不支持数组的API,非常鸡肋。
let arry = [] Object.defineProperty(arry, '0', { get() { console.log("读取成功"); return temp }, set(value) { console.log("设置成功"); temp = value; } }); arry[0] = 10; //触发设置成功 arry.push(10); //不能被劫持
Proxy 可以监听到数组的变化,支持各种API。注意数组的变化触发get和set可能不止一次,如有需要,自行根据key值决定是否要进行处理。
let hobbits = ['travel', 'reading']; let p = new Proxy(hobbits, { get(target, key) { console.log('读取成功'); return Reflect.get(target, key); }, set(target, key, value) { console.log('设置成功'); return Reflect.set(target, key, value); } }); p.splice(0,1) //触发get和set,可以被劫持 p.push('photography');//触发get和set p.slice(1); //触发get;因为 slice 是不会修改原数组的
所以,建议使用 Proxy 监测变量变化
1、shift 2、unshift 3、pop 4、push 5、reverse 6、sort 7、splice(start,length,item) start 指定修改的开始位置(从0计数)。如果是负值,则表示从数组末位开始;如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
start
length 可选 表示要移除的数组元素的个数。如果 length 是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。
length
item 可选 要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
item
8、copyWithin:方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
[1, 2, 3, 4, 5].copyWithin(-2) // [1, 2, 3, 1, 2] [1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5] [1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5]
9、fill(填充数组元素的值,起始索引,终止索引)
const array1 = [1, 2, 3, 4]; console.log(array1.fill(0, 2, 4)); // [1, 2, 0, 0] console.log(array1.fill(5, 1)); // [1, 5, 5, 5]
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Proxy 与 Object.defineProperty的优劣
Object.definedProperty
缺点
defineproperty
监听需要知道是哪个对象的哪个属性,而proxy
只需要知道哪个对象就可以了。也就是会省去for in
循环提高了效率。修改原数据
。而proxy
只是原对象的代理,proxy
会返回一个代理对象不会在原对象上进行改动,对原数据无污染。优点
注意:
Object.defineProperty
定义出来的属性,默认是不可枚举(enumerable: false
),不可更改(writable: false
),不可配置(configurable: false
)Proxy
Proxy 会劫持整个对象,读取对象中的属性或者是修改属性值,那么就会被劫持。但是有点需要注意,复杂数据类型,监控的是引用地址,而不是值,如果引用地址没有改变,那么不会触发set。
最后,我们再看下对于数组的劫持,Object.definedProperty 和 Proxy 的差别
Object.definedProperty 可以将数组的索引作为属性进行劫持,但是仅支持直接对 arry[i] 进行操作,不支持数组的API,非常鸡肋。
Proxy 可以监听到数组的变化,支持各种API。注意数组的变化触发get和set可能不止一次,如有需要,自行根据key值决定是否要进行处理。
Proxy 相比于 defineProperty 的优势:
所以,建议使用 Proxy 监测变量变化
改变原数组的9种方法
1、shift
2、unshift
3、pop
4、push
5、reverse
6、sort
7、splice(start,length,item)
start
指定修改的开始位置(从0计数)。如果是负值,则表示从数组末位开始;如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
length
可选表示要移除的数组元素的个数。如果 length 是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。
item
可选要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。
8、copyWithin:方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。
9、fill(填充数组元素的值,起始索引,终止索引)
The text was updated successfully, but these errors were encountered: