理解 Object.defineProperty 和 Proxy
1 Object.defineProperty(obj, prop, descriptor)
obj
:目标对象prop
:需定义或修改的属性的名字descriptor
:目标属性所拥有的特性
数据描述符有以下键值
1 | let obj = {} |
ps:一旦使用 Object.defineProperty
给对象添加属性,那么如果不设置属性的特性,那么 configurable、enumerable、writable
这些值都为默认的 false
。如果不使用 Object.defineProperty
添加属性,那么 configurable、enumerable、writable
这些值都为默认的 true
存取描述符有以下键值
1 | let obj = {} |
ps:当使用了 getter
或 setter
方法,不允许使用 writable
和 value
这两个属性。
使用示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18let obj = {}
let value = 'old value'
Object.defineProperty(obj,"key",{
get:function (){
//获取值时触发
return value
},
set:function (newvalue){
//设置新值时触发,设置的新值可通过 newvalue 获取
value = newvalue
}
})
//获取值
console.log( obj.key ) // old value
//设置值
obj.key = 'new value'
console.log( obj.key ) // new value
2 new Proxy(target, handler)
Proxy
对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等),通过操作为对象生成的代理器,实现对对象各类操作的拦截式编程target
:要代理的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)handler
:一个对象,其属性是当执行一个操作时定义代理的行为的函数。相当于拦截器,可以有多个拦截操作
使用示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27let handler = {
// set 有3个参数,obj(对象), prop(属性), value(新添加的值),get 有2个参数,obj, prop
set: function(obj, prop, value) {
// 如参数名是 age 就执行如下的判断(报错则无法执行赋值操作,赋值无效)
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer')
}
if (value > 200) {
throw new TypeError('The age seems invalid')
}
}
// 赋值
obj[prop] = value;
}
}
let person = new Proxy({}, handler)
person.age = 100
console.log(person.age) // 100
person.age = 'young' // 抛出异常: Uncaught TypeError: The age is not an integer
person.age = 300 // 抛出异常: Uncaught TypeError: The age seems invalid
person.name = 'Nola' // "Nola"
console.log(person) // Proxy {age: 100, name: "Nola"}
3 Object.defineProperty VS Proxy
Object.defineProperty缺点:
- Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。
- 在Vue中,Object.defineProperty无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。
Proxy优点:
- 可以劫持整个对象,并返回一个新对象。
- Proxy可以直接监听数组的变化
- 有多种劫持操作。
Proxy缺点:
- Proxy是es6提供的新特性,兼容性不好,且这个属性无法用polyfill来兼容。
参考资料:
ECMAScript 6 入门-Proxy
defineProperty VS Proxy
实现双向绑定 Proxy比 defineproperty优劣如何