前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >理解Javascript的Proxy

理解Javascript的Proxy

作者头像
MudOnTire
发布2019-05-26 08:46:48
9450
发布2019-05-26 08:46:48
举报
文章被收录于专栏:MudOnTireMudOnTire

关于Proxy

Proxy在计算机领域是一个很普遍的概念,中文通常翻译为代理,“代理”一般用于描述某人或某事代表他人行事。常见的概念有Proxy Server(代理服务器)、Reverse Proxy(反向代理)、Proxy Pattern(代理模式)等。

为了理解Proxy,我们先问自己几个问题:

  1. 什么是Proxy?上面说过了,代理就是某人或某事代表他人行事。
  2. 为什么需要Proxy?有几种可能,1. 被代理对象不想直接被访问,就像找明星拍戏需要先联系他的经纪人;2. 被代理对象某些能力不足需要找个人帮他做,比如打官司需要找律师。所以Proxy至少可以起到两方面的作用:进行访问控制和增加功能。

理解了上面两个问题,学习Javascript的Proxy就简单多了。

ES6的Proxy

ES6中也出现了Proxy,和其他的Proxy类似,ES6中的Proxy也用于代理某个东西,同样我们需要弄懂几个问题:

  1. Proxy代理什么?代理Object(这是废话,javascript里面所有的东西都是Object)
  2. Proxy代理Object做什么?控制和修改Object的基本行为
  3. 哪些是Object的基本行为?比如属性调用、属性赋值、删除属性、方法调用等
  4. 为什么要控制和修改Object的基本行为?前面讨论过,进行访问控制和增加功能

Proxy用法

基本语法

创建一个proxy:

代码语言:javascript
复制
const p = new Proxy(target, handler);

target:是被代理的对象,可以是对象、数组、方法、构造函数class甚至是另外一个proxy,总之可以是任何JavaScript对象;

handler:一个对象,属性是各种控制或修改target基本行为的方法;

示例

比如用户未设置头像则返回默认头像可以这么写:

代码语言:javascript
复制
const user = { name: 'bruce' };
const userProxy = new Proxy(user, {
  get: (obj, prop) => {
    if (prop === 'avatar') {
      if (!obj.avatar) {
        return 'https://avatar-static.segmentfault.com/100/035/1000355095-5b3c339ebdbe1_big64';
      }
    }
    return obj[prop];
  }
});

console.log(userProxy.avatar); // https://avatar-static···

或者我们可以实现alert换行显示多条信息:

代码语言:javascript
复制
const myAlert = new Proxy(alert, {
  apply: (target, thisArg, argumentsList) => {
    const msg = argumentsList.join('\n');
    target(msg);
  }
});

myAlert('haha', 'lala');
image
image

React源码中也有proxy的应用,用proxy来统一管理event:

代码语言:javascript
复制
/** Proxying after everything set on SyntheticEvent
 * to resolve Proxy issue on some WebKit browsers
 * in which some Event properties are set to undefined (GH#10010)
 */
{
  var isProxySupported = typeof Proxy === 'function' &&
  // https://github.com/facebook/react/issues/12011
  !Object.isSealed(new Proxy({}, {}));

  if (isProxySupported) {
    /*eslint-disable no-func-assign */
    SyntheticEvent = new Proxy(SyntheticEvent, {
      construct: function (target, args) {
        return this.apply(target, Object.create(target.prototype), args);
      },
      apply: function (constructor, that, args) {
        return new Proxy(constructor.apply(that, args), {
          set: function (target, prop, value) {
            if (prop !== 'isPersistent' && !target.constructor.Interface.hasOwnProperty(prop) && shouldBeReleasedProperties.indexOf(prop) === -1) {
              !(didWarnForAddedNewProperty || target.isPersistent()) ? warning_1(false, "This synthetic event is reused for performance reasons. If you're " + "seeing this, you're adding a new property in the synthetic event object. " + 'The property is never released. See ' + 'https://fb.me/react-event-pooling for more information.') : void 0;
              didWarnForAddedNewProperty = true;
            }
            target[prop] = value;
            return true;
          }
        });
      }
    });
    /*eslint-enable no-func-assign */
  }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关于Proxy
  • ES6的Proxy
  • Proxy用法
    • 基本语法
      • 示例
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档