Proxy 是 ES6 的新特性,本篇文章主要写的是我对于 Proxy 特性的初尝试!

尤大发微博了!其中有个重点是 Vue.js 从 3.0 将会通过 Proxy 来替换原本的Object.defineProperty来实现数据响应式。

Proxy 是什么?

根据 MDN 的描述:

Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。

更多关于 Proxy 的特性与实现,大家可以浏览:MDN web docs – Proxy

根据阮一峰老师的ECMAScript 6 入门 - Proxy中的概述:

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

Proxy 接受两个参数。第一个参数是所要代理的目标对象,第二个参数是一个配置对象,对于每一个被代理的操作,需要提供一个对应的处理函数,该函数将拦截对应的操作。

以上语句简单转化为代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let obj = {
string: 'Hello'
};

// obj 为所要代理的目标对象,而第二个参数对象,则是配置对象。
let proxy = new Proxy(obj, {
get: function(target, key, receiver) {
console.log(
'监听到取值的命令了!呐,把' + key + '的值告诉你:' + target[key] + '!'
);
return Reflect.get(target, key, receiver);
},
set: function(target, key, value, receiver) {
console.log(
'监听到赋值命令了!,我要把' + key + '的值改成:' + value + '!'
);
return Reflect.set(target, key, value, receiver);
}
});

proxy.string; // 监听到取值的命令了!呐,把string的值告诉你:Hello!

proxy.string = 'World!'; // 监听到赋值命令了!,我要把string的值改成:World!!

通过以上代码设置了 get()和 set()的拦截器,我们可以在取值或赋值了进行额外的操作,实现了一个不完美的数据响应

Proxy 给了我们很大的想象空间!

ProxyObject.defineProperty()

Object.defineProperty()

我们都知道 Vue.js 之前是通过Object.defineProperty()实现基于数据劫持的数据响应,从而实现数据的双向绑定。

缺点

Object.defineProperty()也存在相应缺点:

通过下标方式修改数组数据给对象新增属性并不会触发数据响应。

(目前 Vue.js 中hack了数组(Array)方法,实现了数组的监听。)

Proxy

通过使用Proxy,我们可以很好的解决上述问题。

Proxy具有以下特点:

  • Proxy可以直接监听到对象,而不仅仅是属性。

  • Proxy可以监听数组的变化。

  • Proxy有很多种拦截方式,一共有 13 种。

根据以上,Proxy可以实现性能的大大提升,也可以实现一些以前需要通过hack手段才能实现的功能。

缺点

Proxy的缺点(个人理解来说可以说是唯一缺点),就是其兼容性问题了。

根据Can I User上的情况,目前对Proxy的兼容性还不是很好。

最后

Proxy给予了我们极大的编程自由度。

目标:希望以后自己也能造出好用易用的轮子!

尤小右快继续更新吧,我还能学的动 :) !