JS Proxy(代理)

<meta charset="utf-8">

Proxy 也就是代理,可以幫助我們完成很多事情,例如對數據的處理,對構造函數的處理,對數據的驗證,說白了,就是在我們訪問對象前添加了一層攔截,可以過濾很多操作,而這些過濾,由你來定義。
想了解更多請參考 官方文檔

語法
  let p = new Proxy(target, handler);
參數

target :需要使用Proxy包裝的目標對象(可以是任何類型的對象,包括原生數組,函數,甚至另一個代理)。
handler: 一個對象,其屬性是當執行一個操作時定義代理的行為的函數(可以理解為某種觸發器)。具體的handler相關函數請查閱官網
下面是使用示例,一個簡單的代理:

  let test = {
    name: "小紅"
  };
  test = new Proxy(test, {
    get(target, key) {
      console.log('獲取了getter屬性');
      return target[key];
    }
  });
  console.log(test.name);
image.png

上方的案例,我們首先創建了一個test對象,里面有name屬性,然后我們使用Proxy將其包裝起來,再返回給test,此時的test已經成為了一個Proxy實例,我們對其的操作,都會被Proxy攔截。
Proxy有兩個參數,第一個是target,也就是我們傳入的*test對象,另一個則是handler,也就是我們傳入的第二個參數,一個匿名對象。在handler中定義了一個名叫get的函數,當我們獲取 test的屬性時,則會觸發此函數。
咱們再來試試使用set來攔截一些操作,并將get返回值更改

  let xiaohong = {
    name: "小紅",
    age: 15
  };
  xiaohong = new Proxy(xiaohong, {
    get(target, key) {
      let result = target[key];
      //如果是獲取 年齡 屬性,則添加 歲字
      if (key === "age") result += "歲";
      return result;
    },
    set(target, key, value) {
      if (key === "age" && typeof value !== "number") {
        throw Error("age字段必須為Number類型");
      }
      return Reflect.set(target, key, value);
    }
  });
  console.log(`我叫${xiaohong.name}  我今年${xiaohong.age}了`);
  xiaohong.age = "aa";
image.png

上方案例中定義了 xiaohong 對象,其中有 age 和 name 兩個字段,我們在Proxy中的 get 攔截函數中添加了一個判斷,如果是取 age 屬性的值,則在后面添加 歲。在 set 攔截函數中判斷了如果是更改 age 屬性時,類型不是 Number則拋出錯誤。最后,正確的輸出了我們想要的結果!
關于return Reflect.set(target, key, value); 這句代碼,可以用其他方式替換,例如 :

  let xiaohong = {
    name: "小紅",
    age: 15
  };
  xiaohong = new Proxy(xiaohong, {
    get(target, key) {
      let result = target[key];
      //如果是獲取 年齡 屬性,則添加 歲字
      if (key === "age") result += "歲";
      return result;
    },
    set(target, key, value) {
      if (key === "age" && typeof value !== "number") {
        throw Error("age字段必須為Number類型");
      }
      target[key] = value;
      // return Reflect.set(target, key, value);
    }
  });
  console.log(`我叫${xiaohong.name}  我今年${xiaohong.age}了`);
  xiaohong.age = 12;
image.png

此時會拋出一個錯誤,因為set函數必須返回一個boolean值,只有返回值為true時才表示修改成功,我們沒有手動return,函數會自動返回undefined,undefined != true,所以報錯是正常的,只需要手動在最后添加一句 return true即可!
但是,既然JS為我們提供了 Reflect ,那我們肯定是使用它啦,畢竟它和Proxy本來就是一起玩的,Proxy有的函數它都有!具體的參考 官方鏈接
這只是最基礎的應用,其他的大家可以自行摸索,都是一樣的用法!
打字不易,點贊的你最靚了...

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前言 Proxy 也就是代理,可以幫助我們完成很多事情,例如對數據的處理,對構造函數的處理,對數據的驗證,說白了,...
    _玖柒_閱讀 111,812評論 2 80
  • 什么是 proxy 代理 Proxy 也就是代理,可以幫助我們完成很多事情,例如對數據的處理,對構造函數的處理,對...
    小李不小閱讀 734評論 0 0
  • 代理(攔截器)是對象的訪問控制,setter/getter 是對單個對象屬性的控制,而代理是對整個對象的控制。 讀...
    Kenzzzzzo閱讀 1,082評論 0 0
  • 前言 今天我們要來講一下Javascript中一個很有趣的類 -- Proxy類,類名翻譯成中文是代理的意思。在真...
    SF_1316閱讀 758評論 0 1
  • 前面的話 ??ES5和ES6致力于為開發者提供JS已有卻不可調用的功能。例如在ES5出現以前,JS環境中的對象包含...
    CodeMT閱讀 1,521評論 0 2