關於ES6中的Proxy


  再當一次搬運工。在思否看到一篇講Proxy的博文,轉發過來,以饗自己。原文出自:理解Javascript的Proxy

一、關於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用法

1.基本語法

創建一個proxy:

const p = new Proxy(target, handler);

target:是被代理的對象,可以是對象、數組、方法、構造函數class甚至是另外一個proxy,總之可以是任何JavaScript對象;

handler:一個對象,屬性是各種控制或修改target基本行為的方法;

示例

比如用戶未設置頭像則返回默認頭像可以這么寫:

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

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

或者我們可以實現alert換行顯示多條信息:

const myAlert = new Proxy(alert, {
  apply: (target, thisArg, argumentsList) => {
    const msg = argumentsList.join('\n');
    target(msg);
  }
});

myAlert('haha', 'lala');

 

 React源碼中也有proxy的應用,用proxy來統一管理event:

 

/** 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 */
  }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM