es6代理proxy

什么是代理

什么是代理?刚开始入行的同学可能就会问了。我们可以这样说,代理Proxy是一个构造函数,它可以接受两个参数:目标对象(target) 与句柄对象(handler) ,返回一个代理对象Proxy,主要用于从外部控制对对象内部的访问。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

创建代理

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例

var proxy = new Proxy(target, handler);

get和set方法

对一个空对象架设了一层拦截,重定义了属性的读取(get)和设置(set)行为。

var obj = new Proxy({}, {
  get: function (target, propKey, receiver) {
    console.log(`getting ${propKey}!`);
    return Reflect.get(target, propKey, receiver);
  },
  set: function (target, propKey, value, receiver) {
    console.log(`setting ${propKey}!`);
    return Reflect.set(target, propKey, value, receiver);
  }
});

对设置了拦截行为的对象obj,去读写它的属性,就会得到下面的结果。

obj.count = 1
//  setting count!
++obj.count
//  getting count!
//  setting count!
//  2

每当代理对象被赋值,处理器函数就会调用,这样就可以用来调试某些问题。

当然了,Proxy可不是仅仅为了调试而诞生的,如果你用过Sencha Touch 或者 AngularJS的话,就会发现这些框架都是类似数据模型绑定的功能。

还可以使用proxy来实现多继承。众所周知,JavaScript中每个对象只能有一个直接的上层原型,从而无法实现多继承

apply方法

apply方法拦截函数的调用、call和apply操作。

var handler = {
  apply (target, ctx, args) {
    return Reflect.apply(...arguments);
  }
};

每当执行proxy函数(直接调用或call和apply调用),就会被apply方法拦截。

var twice = {
  apply (target, ctx, args) {
    return Reflect.apply(...arguments) * 2;
  }
};
function sum (left, right) {
  return left + right;
};
var proxy = new Proxy(sum, twice);
proxy(1, 2) // 6
proxy.call(null, 5, 6) // 22
proxy.apply(null, [7, 8]) // 30

为什么Proxy会取代Object.defineProperty

在Vue2中双向数据绑定原理(数据劫持)采用Object.defineProperty,而在Vue3中数据劫持原理采用的是Proxy代理。

Object.defineProperty只能劫持对象的属性,不能监听数组。也不能对 es6 新产生的 Map,Set 这些数据结构做出监听。也不能监听新增和删除操作等等。
Proxy可以直接监听整个对象而非属性,可以监听数组的变化,具有多达13中拦截方法。

你可能感兴趣的:(前端,es6,javascript,前端)